Stop the Hollyweb! No DRM in HTML5.

[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.

 

posted on 2013-03-13 19:58  灰天飞雁  阅读(451)  评论(0编辑  收藏  举报

填写您的邮件地址,订阅我们的精彩内容:  点击这里给我发消息

添加到收藏夹