BSGS 学习笔记
板子题
题目传送门
题目大意:求关于 的方程 的最小整数解,其中 为质数,且 。(这里换了一下字母,主要是为了方便)
题目解析
因为 为质数,根据欧拉定理/费马小定理可知 ,也就是说,最小解肯定小于 ,这样就可以使用 BSGS 来求解。
算法实现
B(拔)S(山)G(盖)S(世),全称为 baby step gaint step,翻译为小步大步算法,该算法可以用来解关于 的方程 并且满足 在 的解。
算法思路大致如下:
令 ,对 模 讨论。
设 ,其中 且 。
那么原方程就化为
展开得到
其实就是
这样我们只需要先枚举 ,扔到哈希表里面,然后枚举 查询即可。
这样复杂度就由暴力的 降到了 。
说明:由于 式中出现了 在模 意义下的逆元,所以为了保证式子有意义,所以要求 。
代码:
#include<cmath> #include<cstdio> #define db double #define gc getchar #define pc putchar #define U unsigned #define ll long long #define ld long double #define ull unsigned long long #define Tp template<typename _T> #define Me(a,b) memset(a,b,sizeof(a)) Tp _T mabs(_T a){ return a>0?a:-a; } Tp _T mmax(_T a,_T b){ return a>b?a:b; } Tp _T mmin(_T a,_T b){ return a<b?a:b; } Tp void mswap(_T &a,_T &b){ _T tmp=a; a=b; b=tmp; return; } Tp void print(_T x){ if(x<0) pc('-'),x=-x; if(x>9) print(x/10); pc((x%10)+48); return; } #define EPS (1e-7) #define INF (0x7fffffff) #define LL_INF (0x7fffffffffffffff) #define maxn 1000039 #define maxm #define MOD 1000007 #define Type long long #ifndef ONLINE_JUDGE //#define debug #endif using namespace std; Type read(){ char c=gc(); Type s=0; int flag=0; while((c<'0'||c>'9')&&c!='-') c=gc(); if(c=='-') c=gc(),flag=1; while('0'<=c&&c<='9'){ s=(s<<1)+(s<<3)+(c^48); c=gc(); } if(flag) return -s; return s; } struct JTZ{ int flag,x,s; } data[maxn]; void ins(int x,int y){ int pos=x%MOD; while(1){ if(!data[pos].flag){ data[pos].flag=1,data[pos].x=x,data[pos].s=y; return; } else if(data[pos].x==x){ data[pos].s=mmin(data[pos].s,y); return; } pos++; if(pos>=MOD) pos%=MOD; } return; } int find(int x){ int pos=x%MOD; while(1){ if(!data[pos].flag) return -1; else if(data[pos].x==x) return data[pos].s; pos++; if(pos>=MOD) pos%=MOD; } return -1; } ll fastpow(ll x,ll y,ll p){ ll res=1,tmp=x; while(y){ if(y&1) res=res*tmp%p; y>>=1; tmp=tmp*tmp%p; } return res; } ll a,b,p,sp,res,tmp,ans; int main(){ //freopen(".in","r",stdin); //freopen(".out","w",stdout); p=read(); a=read(); b=read(); sp=(ll)ceil(sqrt(p)); res=1; tmp=fastpow(a,sp,p); int i; res=1; for(i=0;i<=sp;i++) ins(b*res%p,i),res=res*a%p; res=1; tmp=fastpow(a,sp,p); for(i=1;i<=sp;i++){ res=res*tmp%p; ans=find(res); if(ans!=-1){ print(i*sp-ans); return 0; } } puts("no solution"); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具