[AHOI2005]SHUFFLE题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1965
各位神犇都不写水题的解题报告,那就我这种弱菜来写吧。
知识储备:扩展gcd的应用及简单同余方程解法。
大意:一开始1~n(2|n)牌依次排列,每次分成等量前后两份,按后1-前1-后2-前2……的顺序依次重新排列,已知牌数N,洗牌次数M,洗牌后扑克牌在第L张,求一开始L的位置。
解法:设Ai表示第i次洗牌后要求的扑克牌的位置,显然A0即为所求。
建立简洁的关系式(一定要简洁,之前的分块做法不方便总结),得Ai=2(Ai-1) mod (N+1)
由迭代及mod的简并性得Am=2m*A0 mod (N+1)。该式Am=L,2m已知,解同余方程A0*2m=Am(mod N+1)即可,此式可用2m mod (N+1)替换2m,用快速幂计算即可,注意不能用sqr防止溢出。
program shuffle;
var
n,m,l,x,y:int64;
Function times(pa,pb,pc:int64):int64;//快速幂
begin
if pb=0 then exit(1);
if pb=1 then exit(pa mod pc);
times:=times(pa,pb shr 1,pc);
times:=times*times mod pc;//不能用sqr!
if odd(pb) then times:=((times mod pc)*pa) mod pc;
end;
Function ExGcd(a,b:int64):int64;//计算A*x+B*y=Gcd(a,b)的一个(x,y)
var
oldx:int64;
begin
if b=0 then
begin
x:=1;
y:=0;
exit;
end;
Exgcd(b,a mod b);
oldx:=x;
x:=y;
y:=oldx-a div b*y;
end;
Function solve(a,b,c:int64):int64;//Ax=B(mod C) 则 Ax-Cy=b,用Exgcd解这个方程得到(x,y)
begin
Exgcd(a,c);
x:=x mod c;
if x<0 then inc(x,c);
x:=x*b mod c;
end;
begin
readln(n,m,l);
writeln(solve(Times(2,m,n+1),l,n+1));
end.

浙公网安备 33010602011771号