Baby Step Gaint Step

给定同余式,求它在内的所有解,其中总是素数。

 

分析:解本同余式的步骤如下

    (1)求模的一个原根

    (2)利用Baby Step Giant Step求出一个,使得,因为为素数,所以有唯一解。

    (3)设,这样就有,其中,那么得到

    (4)求出所有的,可以知道一共有个解,我们求出所有的,然后排个序即可。

 

  O(sqrt(n))的时间复杂度

  BSGS如下(前向星版本)

  
const maxn=200001; type node=record data,next,id:longint; end; type LL=int64; var edge:array [0..maxn] of node; head:array [0..maxn] of longint; cnt:longint; a,b,c:ll; procedure insert(data,id:longint); var i,k:longint; begin k:=data mod maxn; i:=head[k]; while i<>-1 do

    begin

      if edge[i].data=data then exit; edge[cnt].data:=data; edge[cnt].id:=id; edge[cnt].next:=head[k]; head[k]:=cnt; inc(cnt); i:=edge[i].next; end; end; function find(data:ll):longint; var i,k:longint; begin k:=data mod maxn; i:=head[k]; while i<>-1 do

    begin

      if edge[i].data=data then exit(edge[i].id); i:=edge[i].next; end; exit(-1); end; procedure extend_gcd(a,b:ll;var x,y:ll); var t:ll; begin

  if b=0 then

    begin x:=1; y:=0; exit; end; extend_gcd(b,a mod b,x,y); t:=x; x:=y; y:=t-(a div b)*y; end; function gcd(x,y:ll):ll; begin

  if x mod y=0 then exit(y) else exit(gcd(y,x mod y)); end; function modd(x,p:ll):ll; begin

  if x>=p then exit(x mod p); if x<0 then exit((x mod p+p) mod p); exit(x); end; function quick_mod(a,n,p:ll):ll; var ans,t:ll; begin ans:=1; t:=modd(a,p); while n<>0 do

    begin

      if (n and 1)=1 then ans:=modd(ans*t,c); n:=n>>1; t:=modd(t*t,c); end; exit(ans); end; function bsgs(a,b,c:ll):ll; var x,y,k,t,d,len,m:ll; i:longint; begin fillchar(head,sizeof(head),$ff); cnt:=0; b:=modd(b,c); for i:=0 to 100 do

      begin

        if b=t then exit(i); t:=modd(t*a,c); end; d:=1; len:=0; while true do

     begin t:=gcd(a,c); if t=1 then break; if (b mod t)<>0 then exit(-1); c:=c div t; b:=b div t; d:=modd(d*a div t,c); inc(len); end; m:=trunc(sqrt(c)); t:=1; for i:=0 to m do

      begin insert(t,i); t:=modd(t*a,c); end; k:=quick_mod(a,m,c); for i:=0 to m do

      begin extend_gcd(d,c,x,y); t:=modd(b*x,c); if (y=find(t)) and (y<>-1) then exit(i*m+y+len); d:=modd(d*k,c); end; exit(-1); end; begin readln(a,b,c); writeln(bsgs(a,b,c)); end.
View Code

 

你可能感兴趣的:(int)