洗牌
根据题目模拟了几次洗牌过程,得到了第一层逻辑,
i
f
(
x
<
=
(
n
/
2
)
)
x
1
=
2
∗
x
e
l
s
e
i
f
(
x
>
(
n
/
2
)
)
x
1
=
(
x
−
(
n
/
2
)
−
1
)
∗
2
+
1
;
−
>
x
1
=
(
2
∗
x
−
n
−
2
)
+
1
−
>
x
1
=
(
2
∗
x
−
(
n
+
1
)
)
因
为
2
∗
x
−
(
n
+
1
)
<
n
所
以
x
1
=
2
∗
x
(
m
o
d
n
+
1
)
,
总
式
子
也
是
x
1
=
2
∗
x
(
m
o
d
n
+
1
)
题
目
变
为
2
m
∗
x
=
L
(
m
o
d
n
+
1
)
−
>
2
m
∗
x
+
(
n
+
1
)
∗
Y
=
L
if(x<=(n/2))x1=2*x\ \ \ else \ if(x>(n/2))x1=(x-(n/2)-1)*2+1;->x1=(2*x-n-2)+1->x1=(2*x-(n+1))因为2*x-(n+1)<n所以x1=2*x(mod\ n+1),总式子也是x1=2*x(mod \ n+1) 题目变为2 ^ m *x=L(mod\ n+1)->2^ m*x+(n+1)*Y=L
if(x<=(n/2))x1=2∗x else if(x>(n/2))x1=(x−(n/2)−1)∗2+1;−>x1=(2∗x−n−2)+1−>x1=(2∗x−(n+1))因为2∗x−(n+1)<n所以x1=2∗x(mod n+1),总式子也是x1=2∗x(mod n+1)题目变为2m∗x=L(mod n+1)−>2m∗x+(n+1)∗Y=L 扩欧取最小值即可
//package KMP;
import java.util.Scanner;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.LinkedList;
import java.util.Queue;
import java.math.BigInteger;
public class Main {
static long x,y;
public static long exd_gcd(long a,long b)
{
if(b==0)
{
x=1;y=0;
return a;
}
long d=exd_gcd(b,a%b);
y^=x;
x^=y;
y^=x;
y-=(a/b)*x;
return d;
}
public static long res(long s,long mod)
{
exd_gcd(s,mod);
//System.out.println("X"+x+"Y"+y);
return x>0?x%mod:(x%mod+mod)%mod;
}
public static long mul(long a,long b,long mod)
{
long ans=0;
while(b!=0)
{
if((b&1)==1)
ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return ans;
}
public static long quicks(long a,long b,long mod)
{
long ans=1;
while(b!=0)
{
if((b&1)==1)
ans=mul(ans,a,mod);
a=mul(a,a,mod);
b>>=1;
}
//System.out.println("A::"+ans);
return ans;
}
//N M L 长度 洗牌次数 访问的位置
//2^M*X=L(mod N+1) 2^M*x+(N+1)*Y=L
public static void main(String []args)
{
Scanner cin=new Scanner (System.in);
long N,M,L;
N=cin.nextLong();
M=cin.nextLong();
L=cin.nextLong();
long A=quicks(2,M,N+1);
long B=N+1;
//System.out.println(A);
long X=res(A,B);
X=mul(X,L,B)%B;
System.out.println(X);
cin.close();
}
}