终于在bzoj上AC一题了,虽然是看题解写的。。。
program sdoi2011; const err='Orz, I cannot find x!'; maxn=100000; maxm=2; type re=record r,num:longint; end; var gcd,a,b,c:int64;//convenient i,t,ty:longint; ha:array[0..maxn,0..maxm]of re; function safe(x:int64):int64; begin safe:=(x mod c+c) mod c; end; function mi(a,b:int64):int64;//a^b mod c var y,ans:int64; begin y:=a; ans:=1; while b<>0 do begin if b and 1=1 then ans:=ans*y mod c; y:=y*y mod c; b:=b shr 1; end; mi:=ans; end; procedure exgcd(a,b:int64;var x,y:int64); begin if b=0 then begin x:=1;y:=0; gcd:=a; exit; end; exgcd(b,a mod b,y,x); y:=safe(y-a div b*x); end; procedure solve1;//ax+cy=gcd,ax+cy=b var x,y:int64; begin exgcd(a,c,x,y); if b mod gcd<>0 then begin writeln(err); exit; end; x:=safe(x); writeln(safe((b div gcd)*x)); end; function inv(p:int64):int64;//p*x=1 (mod c) var x,y:int64; begin exgcd(p,c,x,y); if gcd=1 then exit((x+c) mod c) else exit(-1); end; procedure addhash(num,r:int64); var hash,i:longint; begin hash:=(num mod maxn+maxn) mod maxn; for i:=1 to maxm do begin if ha[hash,i].r>0 then continue; ha[hash,i].r:=r; ha[hash,i].num:=num; break; end; end; function inhash(b:int64;var post1,post2:int64):boolean; var hash,i:longint; begin hash:=(b mod maxn+maxn) mod maxn; for i:=1 to maxm do begin if ha[hash,i].r=0 then break; if ha[hash,i].num=b then begin post1:=hash; post2:=i; exit(true); end; end; exit(false); end; procedure solve2;//a^x=b (mod c) Baby Step Giant Step var v,now,post1,post2:int64; i,m:longint; begin b:=b mod c; fillchar(ha,sizeof(ha),0); m:=trunc(sqrt(c))+1; v:=inv(mi(a,m));//乘法逆 now:=1; for i:=1 to m do begin now:=(now*a) mod c; addhash(now,i); end; for i:=0 to m-1 do begin if inhash(b,post1,post2) then begin writeln((i*m+ha[post1,post2].r) mod c); exit; end; b:=(b*v) mod c; end; writeln(err); end; begin read(t,ty); for i:=1 to t do begin read(a,b,c); case ty of 1:writeln(mi(a,b)); 2:solve1; 3:solve2; end; end; end.