大步小步模板
(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\n", i*T - Hfind(At)); }else printf("no solution\n");for(At = A, i = 1; i <= T; Herase(At*B%P), i++, (At*=A)%=P);} }