BSGS 以及 ExBSGS

BSGS

引入

求解关于\(X\)的方程,
\[A^X\equiv B \pmod P\]
其中\(Gcd(A,P)=1\)

求解

我们令\(X=i*\sqrt{P}-j\),其中\(0<=i,j<=\sqrt{P}\)
则原式可以变为:
\[A^X\equiv B \pmod P\]
\[A^{i*\sqrt{P}-j}\equiv B \pmod P\]
由于\(Gcd(A,P)=1\),则可以恒等变化为:
\[A^{i*\sqrt{P}}\equiv B*A^j \pmod P\]
则我们可以先预处理出所有的\(A^{i*\sqrt{P}}\),存入哈希表。
再枚举\(B*A^j\),在哈希表里查找即可得解。

代码

int quick_Pow(int x,int y,int p){
    if(y==0)return 1;
    if(y==1)return x;
    if(y%2)return 1ll*x*quick_Pow(1ll*x*x%p,y/2,p)%p;
    return quick_Pow(1ll*x*x%p,y/2,p);
}
void BSGS(int x,int y,int p){
    x%=p;y%=p;
    if(x==0&&y!=0){puts("-1");return ;}
    if(x==0&&y==0){puts("1");return ;}
    if(y==1){puts("0");return ;}
    int st=int(sqrt(p))+1;Mp.clear();
    for(int i=1,rt=1;i<=st;i++,rt=(1ll*rt*x)%p)Mp[rt]=i;
    int sum=quick_Pow(x,st,p);
    for(int i=1,rt=1;i<=st;i++){
        rt=(1ll*rt*sum)%p;
        if(Mp[rt]){
            printf("%d\n",i*st-Mp[rt]);
            return ;
        }
    }
    puts("-1");
}

ExBSGS

引入

求解关于\(X\)的方程,
\[A^X\equiv B \pmod P\]
其中\(Gcd(A,P)\)无特殊条件。

由于\(Gcd(A,P)\)可能不为\(1\),所以\(A\)关于\(P\)可能没有逆元。
故不能用一般的 BSGS 求解。

求解

我们设\(D=Gcd(A,P)\),
则显然有 \(\frac{A}{D}\equiv 1\pmod P\)
则原式\[A^X\equiv B \pmod P\]
可恒等变形为\[A^{X-1}\cdot\frac{A}{D}\equiv \frac{B}{D} \pmod {\frac{P}{D}}\]
而由于\(Gcd(\frac{A}{D},\frac{P}{D})=1\),则有
\[A^{X-1}\equiv \frac{B}{D}\cdot({\frac{A}{D}})^{-1} \pmod {\frac{P}{D}}\]
则此时\(\frac{P}{D}\)就相当于新的\(P\)值,\(\frac{B}{D}\cdot({\frac{A}{D}})^{-1}\)就相当于新的\(B\)值,
就可以这样递推下去了。(注:下一次的\(D\)是新的\(P\)值与\(A\)的\(Gcd\))

考虑边界状态:
①:若当前的\(D=1\),则问题转化为普通的 BSGS。
②:若\(B\)值等于\(1\)了,则迭代到的\(Ans\)值为\(1\)。
③:若\(D \not| B\),即\(D\)不是\(B\)的因数,则\(\frac{B}{D}\)没有意义,则无解。

综上,出解。

例题及代码

板题
题意:求满足\(A^X\equiv B \pmod{P}\)的最小整数\(X\)

#include<map>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<tr1/unordered_map>
using namespace std;
#define LL long long
tr1::unordered_map<LL,int>Mp;
LL Gcd(LL x,LL y){
    if(x==0)return y;
    return Gcd(y%x,x);
}
LL quick_Pow(LL x,LL y,LL p){
    if(y==0)return 1;
    if(y==1)return x;
    if(y%2)return x*quick_Pow(x*x%p,y/2,p)%p;
    return quick_Pow(x*x%p,y/2,p);
}
int ExBSGS(int x,int y,int p){
    if(y==1)return 0;//特判解为0的情况.
    LL k=0,a=1;
    while(1){
        int d=Gcd(x,p);if(d==1)break;
        if(y%d)return -1;
        y/=d;p/=d;k++;a=(1ll*a*x/d)%p;
        if(a==y)return k;//同特判.
    }Mp.clear();
    LL st=int(sqrt(p))+1,sum=quick_Pow(x,st,p);
    for(LL i=0,rt=y;i<=st;i++,rt=(1ll*rt*x)%p)Mp[rt]=i+1;
    for(LL i=1,rt=(a*sum)%p;i<=st;i++,rt=(1ll*rt*sum)%p){//不将求解中的A/D移项.
        if(!Mp[rt])continue;
        return 1ll*i*st-(Mp[rt]-1)+k;
    }
    return -1;
}
int A,B,C;
int main(){
    while(~scanf("%d%d%d",&A,&B,&C)&&A){
        int Ans=ExBSGS(A,C,B);
        if(Ans!=-1)printf("%d\n",Ans);
        else puts("Orz,I can’t find D!");
    }
}

注:一般的,题目所给的A,B,C都是正整数。

原文地址:https://www.cnblogs.com/ftotl/p/11621342.html

时间: 2024-10-11 06:13:49

BSGS 以及 ExBSGS的相关文章

BSGS与ExBSGS:大步小步法

BSGS与ExBSGS:大步小步法 朴素BSGS \(BSGS\)也就是\(Baby~ Step~ Giant~ Step\),用以解决形如以下的问题: 求解\(A^x \equiv B (mod~C)\)的最小整数解.其中\(A\)与\(C\)互质. 设\(x = am - b\)则原式变为 \[ A^{am-b}\equiv B(mod~C) \] \[ A^{am}\equiv B\times A^b(mod~C) \] 然后我们假设\(m = \sqrt {C}\)则\(a \in [1

知识点简单总结——BSGS与EXBSGS

知识点简单总结--BSGS与EXBSGS BSGS 给出 $ A,B,C,(A,C)=1 $ ,要你求最小的 $ x $ ,使得 $ A^x \equiv B(mod \ C) $ . 在数论题中经常会看见这样的式子,而它的用处确实也不少,例如: 求指标 ...想不到了(被打) 解题思路 众所周知 $ A^{x} \equiv A^{x \ mod \ \phi (C) }(mod \ C) $ 所以考虑暴力枚举就可以. 但是我们显然要考虑一个更快的. 分块就好了. 设块大小 $ m $ ,预处

省选算法学习-BSGS与exBSGS

前置知识 扩展欧几里得,快速幂 都是很基础的东西 扩展欧几里得 说实话这个东西我学了好几遍都没有懂,最近终于搞明白,可以考场现推了,故放到这里来加深印象 翡蜀定理 方程$ax+by=gcd(a,b)$一定有整数解 证明: 因为$gcd(a,b)=gcd(b,a$ $mod$ $b)$ 所以假设我们已经求出来了$bx+(a$ $mod$ $b)y=gcd(b,a$ $mod$ $b)$的一组整数解$(p,q)$ 因为$a$ $mod$ $b=a-(\lfloor \frac{a}{b} \rflo

BSGS和EXBSGS

也许更好的阅读体验 \(Description\) 给定\(a,b,p\),求一个\(x\)使其满足\(a^x\equiv b\ \left(mod\ p\right)\) \(BSGS\) \(BSGS\)可以解决\(p\)为质数的情况 令 \(m=\lceil \sqrt p\rceil\) 令 \(x=i\cdot m-k\) 有 \(a^{i\cdot m-k} \equiv b\ (mod\ p)\) 两边同乘 \(a^k\) 得 \(a^{i\cdot m}\equiv b\cdot

OI知识汇总

以作者的水平为准 基础算法:枚举——>倍增 差分(前缀和)——>二维 贪心 分治:归并排序(逆序对) 二分答案 二分查找 快速排序——>离散化 递归/递推 搜索:深搜(所有方案),宽搜(最优解) DFS优化:迭代 最优性剪枝/可行性剪枝/搜索顺序 记忆化搜索 折半搜索 A*/IDA* BFS优化:双向BFS 判重(康托展开) 优先队列搜索 DP:线性DP(LIS/LCS)  O(nlogn)算法 区间DP 树形DP 背包类DP(01背包,完全背包,多重背包) 数位DP DP优化:排除冗余

BSGS&amp;EXBSGS 大手拉小手,大步小步走

BSGS代码: #include<cstdio> #include<algorithm> #include<cmath> #include<iostream> #include<map> #include<cstring> using namespace std; typedef long long ll; const int N=46349; const int mod=100003; ll p,A,B; ll ni[N]; str

[note]BSGS &amp; exBSGS

BSGS (感觉这东西还是要写一下) BSGS主要用于求解形如\(x^k=y\pmod p\)(注意这里p与x互质)这样的方程的最小正整数解的问题 设\(m=\lceil\sqrt p\rceil,k=am-b,a\in[1,m],b\in[0,m)\) 那么上面的方程可以变形成\(x^{am}=yx^b\pmod p\) 枚举\(b\),计算出右边的值存到\(map\)中,枚举\(a\)查表即可 Q:可以枚举左边存表,右边查嘛? A:可以,但是左边查到表可以直接输出... 顺便一说,map里要

bzoj 3283 扩展BSGS + 快速阶乘

T2  扩展BSGS T3 快速阶乘 给定整数n,质数p和正整数c,求整数s和b,满足n! / pb = s mod pc 考虑每次取出floor(n/p)个p因子,然后将问题转化为子问题. 1 /************************************************************** 2 Problem: 3283 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:1704 ms 7 Memor

【BZOJ1467/2480】Pku3243 clever Y/Spoj3105 Mod EXBSGS

[BZOJ1467/2480]Pku3243 clever Y/Spoj3105 Mod Description 已知数a,p,b,求满足a^x≡b(mod p)的最小自然数x. Input 每个测试文件中最多包含100组测试数据. 每组数据中,每行包含3个正整数a,p,b. 当a=p=b=0时,表示测试数据读入完全. Output 对于每组数据,输出一行. 如果无解,输出“No Solution”(不含引号),否则输出最小自然数解. Sample Input 5 58 33 2 4 3 0 0