[AHOI2005]洗牌
阿新 • • 發佈:2020-08-10
https://www.luogu.com.cn/problem/P2054
設 n=2m
為了方便進行有關剩餘系的推導
把原本的標號1.....2m
改為0......2m-1
發現原本在位置x的牌
經過
#include<bits/stdc++.h> #define N 110000 #define eps 1e-7 #define inf 1e9+7 #define db double #define ll long long #define ldb long double #define ull unsigned long long using namespace std; inline ll read() { char ch=0; ll x=0,flag=1; while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;} while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0',ch=getchar();} return x*flag; } ll mo; ll ksc(ll x,ll y,ll p){return ((x*y-(ll)(((ldb)x*y+0.5)/p)*p)%p+p)%p;} ll ksm(ll x,ll k) { ll ans=1; while(k) { if(k&1)ans=ksc(ans,x,mo); k>>=1;x=ksc(x,x,mo); } return ans; } ll X,Y; ll exgcd(ll a,ll b) { if(!b){X=1;Y=0;return a;} ll d=exgcd(b,a%b),t=X; X=Y;Y=t-(a/b)*Y; return d; } int main() { ll n=read(),m=read(),l=read();mo=n+1; ll a=ksm(2,m),b=mo,d=exgcd(a,b),p1=b/d; X=(X%p1+p1)%p1;X=ksc(X,(l/d),p1); printf("%lld",X); return 0; }