由样例可以得到
1−>2,2−>4,3−>6,4−>1,5−>3,6−>5
.
可以得出一次洗牌后
pos[i]=(2i)mod(n+1)
那么经过
m
次洗牌后,初始位置为
最后也就是求不定方程
2m∗x≡Lmod(n+1)
最小正整数解。
快速幂+快速乘( L∗X 会爆 longlong )
【代码】
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#define N 10000005
#define INF 0x7fffffff
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
ll read()
{
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
ll n,m,L,X,Y;
ll Qpow(ll x,ll y)
{
ll rtn=1;
while(y)
{
if(y&1) rtn=rtn*x%n;
x=x*x%n;y>>=1;
}
return rtn;
}
ll Qmul(ll x,ll y)
{
ll rtn=0;
while(y)
{
if(y&1) rtn=(rtn+x)%n;
x=(x<<1)%n;y>>=1;
}
return rtn;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
ll rtn=a;
if(b) {
rtn=exgcd(b,a%b,y,x);
y-=(a/b)*x;
}
else x=1,y=0;
return rtn;
}
int main()
{
n=read()+1,m=read(),L=read();
ll Gcd=exgcd(Qpow(2,m),n,X,Y);
X=Qmul(X,L);
while(X<=0) X+=n/Gcd;
printf("%lld\n",X);
return 0;
}