BZOJ 1965 洗牌 [快速乘+快速幂]

BZOJ1965: [Ahoi2005]SHUFFLE 洗牌

题面略。

 

题解:

一看这种题,看数据就知道找规律。我们发现:变换的规律为 (1->2,2->4,3->6,4->1,5->3,6->5)  则 pos[a]=a*2%(n+1)。

所以设答案为 X,则X*(2^m)=l%(n+1)  ,这里就要用到逆元和快速幂了。

还有这里要注意,数据范围为 10^10,所以要用快速乘,否则会爆。

 

代码如下:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll mul(ll a,ll b,ll m)  //  和快速幂思想一样,把乘数二进制分解,然后加起来
 5 {
 6     ll res=0;
 7     for (ll i=b; i; i>>=1,a=(a+a)%m)
 8       if (i&1) res=(res+a)%m;
 9     return res;
10 }
11 ll qpow(ll a,ll b,ll m)
12 {
13     ll res=1;
14     for (ll i=b; i; i>>=1,a=mul(a,a,m))
15       if (i&1) res=mul(res,a,m);
16     return res;
17 }
18 int main()
19 {
20     ll n,m,l,ans;
21     scanf("%lld%lld%lld",&n,&m,&l);
22     ans=l*qpow(n/2+1,m,n+1);
23     printf("%lld\n",(ans+n+1)%(n+1));
24     return 0;
25 }
View Code

 

 

 

 

加油加油加油!!!fighting fighting fighting!!!

 
 
标签: dp

 

posted on 2018-08-02 16:07  Frank-King  阅读(193)  评论(0编辑  收藏  举报