大步小步模板
(hash稍微有一点麻烦, poj不支持C++11略坑)
#include <iostream> #include <vector> #include <cstring> #include <cstdio> #include <cmath> #include <map> #define pb push_back #define fi first #define se second #define mk make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; LL A, B, P, phi, T; const int MOD = 1e6+123456; vector<PII> H[MOD+5]; LL qpow(LL a, LL b, LL P){ LL ans = 1; for(; b; b >>= 1, (a*=a)%=P) if(b&1) (ans*=a)%=P; return ans; } inline void Hinsert(LL x, int v){ H[x%MOD].pb(mk(x, v)); } inline void Herase(LL x) { H[x%MOD].clear(); } inline int Hfind(LL x){ int u = x%MOD; for(int i = 0; i < H[u].size(); i++) if(H[u][i].fi == x) return H[u][i].se; return 0; } int main() { while(scanf("%lld %lld %lld", &P, &A, &B) != EOF){ phi = P-1; T = sqrt(phi+0.5); int i; LL At = A, AA; for(i = 1; i <= T; Hinsert(At*B%P, i), i++, (At*=A)%=P); AA = qpow(A, T, P); At = AA; for(i = 1; i*T <= P && !Hfind(At); i++, (At*=AA)%=P); //<=P 恰好可以覆盖0~P-1这些情况 if(Hfind(At)){ printf("%lld ", i*T - Hfind(At)); } else printf("no solution "); for(At = A, i = 1; i <= T; Herase(At*B%P), i++, (At*=A)%=P); } }