标签:turn 枚举 space res c++ lse ++i namespace highlight
#include<cstdio> #include<algorithm> #include<cmath> #include<map> using namespace std; typedef long long ll; ll p,a,b; ll ksm(ll x,ll y) { ll res=1; while(y) { if(y&1)res=res*x%p; y>>=1; x=x*x%p; } return res; } map<ll,ll> h; ll solve(ll a,ll b,ll p) //设x=im-c,则x+c=im //a^x * a^c =a^im { ll m=ceil(sqrt(p));//向上取整 h.clear(); for(ll i=0; i<m; i++) //求出b*a,b*a^2,b*a^3...即等式左边那一段,放到map中 { if(!h.count(b)) h[b]=i; b=b*a%p; } ll now=1,base=ksm(a,m); for(ll i=1; i<=m+1; i++) //枚举i,算a^im的结果,然后到hash表中去找 { now=now*base%p; if(h.count(now))return i*m-h[now]; } return -1; } int main() { while(scanf("%lld%lld%lld",&p,&a,&b)!=EOF) { ll ans=solve(a,b,p); if(ans==-1)printf("no solution\n"); else printf("%lld\n",ans); } return 0; } #include<bits/stdc++.h> using namespace std; pair<long long, long long> x[1000001]; long long p, b, n; long long pow(long long x, long long y, long long p) { long long ans = 1; while(y) { if(y & 1) ans *= x, ans %= p; y >>= 1; x *= x; x %= p; } return ans; } long long find(long long l, long long r, long long v) { while(l <= r) { long long mid = (l + r) / 2; if(x[mid].first < v) { l = mid + 1; } else{ r= mid-1; } } return (x[l].first == v) ? l : -1; } int main() { cin >> p >> b >> n; //b^x =N % p long long sq = (double)(sqrt(p - 2) + 0.5); x[0].first = 1; x[0].second = 0; for(long long i = 1; i < sq; ++i) //求出b的若干次方Mod P的结果,放到一个表里 { x[i].first = x[i - 1].first * b; x[i].first %= p; x[i].second = i; } sort(x, x + sq - 1);//排序 for(long long i = 0; i <= sq; ++i) { long long v = n * pow(b, p - 1 - i * sq, p); v %= p; long long j = find(0, sq - 1, v);//到表里去找 if(j != -1) { cout << i * sq + x[j].second << endl; return 0; } } cout << "no solution" << endl; return 0; }
bzoj3929 Discrete Logging 大步小步算法
标签:turn 枚举 space res c++ lse ++i namespace highlight
原文地址:https://www.cnblogs.com/cutemush/p/11990960.html