题目描述
已知数a,p,b,求满足a^x≡b(mod p)的最小自然数x。
输入输出格式
输入格式:每个测试文件中最多包含100组测试数据。
每组数据中,每行包含3个正整数a,p,b。
当a=p=b=0时,表示测试数据读入完全。
输出格式:对于每组数据,输出一行。
如果无解,输出“No Solution”(不含引号),否则输出最小自然数解。
输入输出样例
说明
100%的数据,a,p,b≤1e9。
x
#include"bits/stdc++.h" using namespace std; typedef long long ll; unordered_map <ll,ll> mp; ll a,b,p; ll bsgs(ll a,ll b,ll p) { if(b==1)return 0; ll d; ll k=1; int cnt=0; while ((d=__gcd(a,p))^1) { if(b%d)return -1; // 不能整除,return ; b/=d; p/=d;cnt++; k=1ll*k*(a/d)%p; if(k==b)return cnt; // a/d 的乘积等于现在的b,然后就能约掉,左边x取cnt,为0次幂 // cout<<k<<" "<<a<<" "<<b<<" "<<p<<endl; } int m=sqrt(p)+1; ll kt=1; mp.clear(); for (int i=0;i<m;i++)// 左边小步 { mp[1LL*kt*b%p]=i; kt=kt*a%p; // 这里最后kt是a^ml } k=k*kt%p; for (int i=1;i<=m;i++)// 右边大步 { if(mp.find(k)!=mp.end()) return i*m-mp[k]+cnt; // 查表 k=k*kt%p; } return -1; } int main() { while (cin>>a>>p>>b) { if(!a&&!b&&!p)break; // cout<<123<<endl; ll ans=bsgs(a,b,p); if(ans!=-1)printf("%lld ",ans); else puts("No Solution"); // cout<<123<<endl; } }