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.

时间: 2024-08-02 21:24:19

Baby Step Gaint Step的相关文章

BSGS算法 (小步大步 Baby Step Gaint Step)

当你要求满足: $$ A^x \equiv B \ (\bmod \ P) $$ 的最小非负整数 x (gcd(A,P)==1)就可以用到 BSGS 了 设 $ m=\sqrt{P} $ 向上取整 处理一下那个式子: $$ A^{i \times m-j} \equiv B \ (\bmod \ P) $$$$ A^{i \times m} \equiv B \times A^j \ (\bmod \ P) $$ 枚举 j(0到m),将 B*A^j 存入hash表里面枚举 i(1到m),从has

数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)

什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSGS算法中是要求a^m在%c条件下的逆元的,如果a.c不互质根本就没有逆元.) 如果x有解,那么0<=x<C,为什么? 我们可以回忆一下欧拉定理: 对于c是素数的情况,φ(c)=c-1 那么既然我们知道a^0=1,a^φ(c)=1(在%c的条件下).那么0~φ(c)必定是一个循环节(不一定是最小的)

HDU 2815 扩展baby step giant step 算法

题目大意就是求 a^x = b(mod c) 中的x 用一般的baby step giant step 算法会超时 这里参考的是http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 map平衡树查找值 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 #include <

【poj2417】baby step giant step

最近在学习数论,然而发现之前学的baby step giant step又忘了,于是去翻了翻以前的代码,又复习了一下. 觉得总是忘记是因为没有彻底理解啊. 注意baby step giant step只能用在b和p互质的情况下,因为只有b和p互质的情况下,b才有mod p下的逆元.(下面要用到逆元) 当b和p不互质,就要处理一下.现在就正在做这么一题,方法以后再写. 求a^(-m)就用到了求逆元了,那么如何求逆元呢?我学了两种方法: ·1:欧拉定理:当a和n互质,a^φ ( n) ≡ 1(mod

HDU 2815 Mod Tree 离散对数 扩展Baby Step Giant Step算法

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2815 题意: 思路:与上题不同,这道题不要求m是素数,是利用扩展Baby Step Giant Step算法求离散对数. 以下转载自:AekdyCoin [扩展Baby Step Giant Step] [问题模型] 求解 A^x = B (mod C) 中 0 <= x < C 的解,C 无限制(当然大小有限制--) [写在前面] 这个问题比较麻烦,目前网络上流传许多版本的做法,不过大部分已近被证明

POJ 2417 Discrete Logging ( Baby step giant step )

Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3696   Accepted: 1727 Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, b

Git Step by Step – (8) Git的merge和rebase

前面一篇文章中提到了"git pull"等价于"git fetch"加上"git merge",然后还提到了pull命令支持rebase模式,这篇文章就介绍一下merge和rebase之间有什么差别. 由于我们主要是想看看merge跟rebase之间的区别,这里就是用本地仓库的分支进行演示了. merge 其实在介绍分支的那篇文章中已经介绍过了一些分支merge的内容,这里就进行一些补充和总结. 下面我们基于本地一个仓库开始介绍,当前仓库的分支情

C# 2012 step by step 学习笔记8 CHAPTER 9 Creating Value types with enumerations and Structures

C# 2012 step by step 学习笔记8 CHAPTER 9 Creating Value types with enumerations and Structures things about 1. Declare an enumeration type. 2. Create and use an enumeration type. 3. Declare a structure type. 4. Create and use a structure type. 5. Explain

Linux Booting Process: A step by step tutorial for understanding Linux boot sequence

One of the most remarkable achievement in the history of mankind is computers. Another amazing fact about this remarkable achievement called computers is that its a collection of different electronic components, and they work together in coordination