码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ】【1965】SHUFFLE 洗牌

时间:2015-02-04 18:07:38      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

扩展欧几里德+快速幂

  每次转换位置:第x位的转移到2*x %(n+1)这个位置上

  那么m次后就到了(2^m)*x %(n+1)这个位置上

  那么找洗牌m次后在 l 位置上的牌就相当于解线性模方程: (2^m)*x ≡ l (mod n+1)  扩展欧几里得即可

技术分享
 1 /**************************************************************
 2     Problem: 1965
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:0 ms
 7     Memory:1272 kb
 8 ****************************************************************/
 9  
10 //BZOJ 1965
11 #include<cstdio>
12 #include<cstring>
13 #include<cstdlib>
14 #include<iostream>
15 #include<algorithm>
16 #define rep(i,n) for(int i=0;i<n;++i)
17 #define F(i,j,n) for(int i=j;i<=n;++i)
18 #define D(i,j,n) for(int i=j;i>=n;--i)
19 using namespace std;
20 int getint(){
21     int v=0,sign=1; char ch=getchar();
22     while(!isdigit(ch)) {if(ch==-) sign=-1; ch=getchar();}
23     while(isdigit(ch))  {v=v*10+ch-0; ch=getchar();}
24     return v*sign;
25 }
26 /*******************template********************/
27 typedef long long LL;
28 LL n,m,l,x,y;
29 LL pow(LL x){
30     LL ans=1,base=2;
31     while(x){
32         if(x&1) ans=(ans*base)%(n+1);
33         base=base*base%(n+1);
34         x>>=1;
35     }
36     return ans;
37 }
38 void exgcd(LL a,LL b,LL &d,LL &x, LL &y){
39     if (!b) {d=a; x=1; y=0; return;}
40     else{ exgcd(b,a%b,d,y,x); y-=x*(a/b);}
41 }
42 int main(){
43     scanf("%lld%lld%lld",&n,&m,&l);
44     LL a=pow(m),b=n+1,d;
45     exgcd(a,b,d,x,y);
46     x=(x*l/d)%b;
47     while(x<0) x+=b;
48     printf("%lld\n",x);
49     return 0;
50 }
View Code

 

【BZOJ】【1965】SHUFFLE 洗牌

标签:

原文地址:http://www.cnblogs.com/Tunix/p/4272789.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!