bzoj1319
数论
这个幂指数很难搞,那么我们取个log
去取log得有底数,那么自然这个底数能表示出所有的数
原根满足这个性质
那么我们求出原根,再去log
变成k*ind(x)=ind(a) (mod phi(p))
phi(p)=p-1
又因为g^ind(a)=a (mod p)
那么我们用bsgs求出ind(a)
那么我们就要解出ind(x)的所有解,用exgcd
然后求出最小自然数数解,然后通解是x+b*t
那么每次加b就行了
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 5; int p, k, a, top; ll Ans[N], st[N]; ll power(ll x, ll t) { ll ret = 1; for(; t; t >>= 1, x = x * x % p) if(t & 1) ret = ret * x % p; return ret; } int find_root(int p) { if(p == 2) return 1; int tmp = p - 1; for(int i = 2; i * i <= p; ++i) if(tmp % i == 0) { st[++top] = i; while(tmp % i == 0) tmp /= i; } if(tmp != 1) st[++top] = tmp; for(int g = 2; g < p; ++g) { bool flag = true; for(int j = 1; j <= top; ++j) { if(power(g, (p - 1) / st[j]) == 1) { flag = false; break; } } if(flag) return g; } return -1; } int bsgs(int a, int b, int p) { map<ll, int> mp; int m = sqrt(p); ll x = 1, pw = power(a, m); for(int i = 0; i <= m; ++i) { mp[x] = i * m; x = x * pw % p; } x = 1; for(int i = 0; i < m; ++i) { ll tmp = power(x, p - 2) * b % p; if(mp.find(tmp) != mp.end()) return mp[tmp] + i; x = x * a % p; } } ll exgcd(ll a, ll b, ll &x, ll &y) { if(b == 0) { x = 1; y = 0; return a; } int ret = exgcd(b, a % b, y, x); y -= (a / b) * x; return ret; } int main() { cin >> p >> k >> a; ll g = find_root(p), c = bsgs(g, a, p), b = p - 1, x, y, gcd = exgcd(k, b, x, y); if(c % gcd != 0) return puts("0"), 0; c /= gcd; b /= gcd; k /= gcd; x = (x * c % b + b) % b; while(x < p) { Ans[++Ans[0]] = power(g, x); x += b; } sort(Ans + 1, Ans + Ans[0] + 1); printf("%d\n", Ans[0]); for(int i = 1; i <= Ans[0]; ++i) printf("%lld\n", Ans[i]); return 0; }