2018.11.07 bzoj1965: [Ahoi2005]SHUFFLE 洗牌(快速幂+exgcd)
程序员文章站
2022-04-02 21:30:45
...
传送门
发现自己的程序跑得好慢啊233.管他的反正AC了
先手玩样例找了一波规律发现题目要求的就是
然后脑补了一波数学证明。
假设当前牌在第个位置(为了方便假设在左半边,右半边的差不多)。
然后在这一次洗牌之后会有张牌在它的前面。
于是它移到了第个位置。
证毕。
然后为了防止爆我手写了一个快速乘估计就是这个地方慢了(都是借口明明是自己菜。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,l,a,b;
inline ll ksc(ll x,ll p,ll mod){ll ret=0;for(;p;p>>=1,x=(x+x)%mod)if(p&1)ret=(ret+x)%mod;return ret;}
inline ll ksm(ll x,ll p,ll mod){ll ret=1;for(;p;p>>=1,x=ksc(x,x,mod))if(p&1)ret=ksc(ret,x,mod);return ret;}
inline ll gcd(ll a,ll b){while(b){ll t=a;a=b,b=t%a;}return a;}
inline void exgcd(ll a,ll b,ll&x,ll&y){
if(!b){x=1,y=0;return;}
exgcd(b,a%b,x,y);
ll tmp=x;
x=y,y=tmp-a/b*y;
}
int main(){
cin>>n>>m>>l,a=ksm(2ll,m,n+1),b=n+1;
ll g=gcd(a,b),x,y;
a/=g,b/=g,l/=g;
exgcd(a,b,x,y);
x=(ksc(x,l,b)+b)%b;
cout<<x;
return 0;
}
上一篇: F - Finding Sasuke