高次同余方程

求解 axb(modp).

大步小步算法,BSGSbabystepgiantstep,要求 gcd(a,p)=1,可在 O(p) 时间复杂度内求解。

p<=1016 时没有大问题。

方程的解满足 0<=x<p.

t=p,0<=j<t,x=itj,则 aitjb(modp).

两边同时乘上 aj 可得,aitbaj(modp).

对于所有的 j[0,t1],将 baj 插入 hash/map 中。

枚举所有的 i[0,t],查找表中是否存在 ait,若存在则可以得到对应的 jx=itj.

inline int BSGS(int a,int b,int p){
a%=p;
b%=p;
if(b==1)return 0;
mp.clear();
int t=sqrt(p)+1,re=1;/*初值a^0*/
for(int i=0;i<t;i++)mp[re*b%p]=i,(re*=a)%=p;/*依次插入b*a^i*/
a=re;/*re=a^t%p*/
re=1;
for(int i=0;i<=t;i++){
int j=mp.find(re)==mp.end()?-1:mp[re];
if(j>=0&&i*t-j>=0)return i*t-j;
(re*=a)%=p;
}
return -1;
}

扩展BSGS算法

求解 axb(modp)gcd(a,p)1.

将不互质的情况转化为互质的情况,设 g=gcd(a,p),两边同时除以 g.

得到,axgbg(modpg),即 ax1agbg(modpg).

gbb1 时无解。

一直递归直到 gcd(a,p)=1,假设一共递归了 cnt 次,设 d=i=1kgi.

原式即,axcntacntdbd(modpg).

于是用 a,bg,pgBSGS ,注意还有一个系数 acntd 要乘进去,出入 BSGS 中。

inline int BSGS(int a,int b,int p,int ad){
a%=p,b%=p;
mp.clear();
int t=sqrt(p)+1,re=1;
for(int i=0;i<t;i++)mp[re*b%p]=i,(re*=a)%=p;
a=re;
re=ad;
for(int i=0;i<=t;i++){
int j=mp.find(re)==mp.end()?-1:mp[re];
if(j>=0&&i*t-j>=0)return i*t-j;
(re*=a)%=p;
}
return -1;
}
inline int exBSGS(int a,int b,int p){
a%=p;
b%=p;
if(b==1||p==1)return 0;/*特判*/
int cnt=0,g=gcd(a,p),ad=1;
while(g>1){
if(b%g)return -1;/*判断无解*/
cnt++;/*累加次数*/
b/=g;
p/=g;
(ad*=a/g)%=p;/*更新系数*/
if(ad==b)return cnt;/*ad=b则前面的一项a的指数为0,直接返回cnt*/
g=gcd(a,p);
}
int ans=BSGS(a,b,p,ad);
if(ans==-1)return -1;
return ans+cnt;
}

也可以不将系数传进去,将 b 乘上系数的逆元即可,注意用 exgcd 计算。

inline int inv(int a,int p){
int x,y;
exgcd(a,p,x,y);
return (x%p+p)%p;
}
inline int BSGS(int a,int b,int p){
a%=p,b%=p;
mp.clear();
int t=sqrt(p)+1,re=1;
for(int i=0;i<t;i++)mp[re*b%p]=i,(re*=a)%=p;
a=re;
re=1;
for(int i=0;i<=t;i++){
int j=mp.find(re)==mp.end()?-1:mp[re];
if(j>=0&&i*t-j>=0)return i*t-j;
(re*=a)%=p;
}
return -1;
}
inline int exBSGS(int a,int b,int p){
a%=p;
b%=p;
if(b==1||p==1)return 0;
int cnt=0,g=gcd(a,p),ad=1;
while(g>1){
if(b%g)return -1;
cnt++;
b/=g;
p/=g;
(ad*=a/g)%=p;
if(ad==b)return cnt;
g=gcd(a,p);
}
int ans=BSGS(a,b*inv(ad,p)%p,p);/*乘上系数的逆元*/
if(ans==-1)return -1;
return ans+cnt;
}
posted @   半步蒟蒻  阅读(73)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示