码迷,mamicode.com
首页 > 其他好文 > 详细

Baby Step Gaint Step

时间:2014-10-29 16:36:21      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   color   os   ar   for   sp   

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

 

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

    (1)求模bubuko.com,布布扣的一个原根bubuko.com,布布扣

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

    (3)设bubuko.com,布布扣,这样就有bubuko.com,布布扣,其中bubuko.com,布布扣,那么得到bubuko.com,布布扣

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

 

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

  BSGS如下(前向星版本)

  bubuko.com,布布扣
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

 

Baby Step Gaint Step

标签:style   blog   http   io   color   os   ar   for   sp   

原文地址:http://www.cnblogs.com/logichandsome/p/4059689.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!