結果
問題 | No.981 一般冪乗根 |
ユーザー |
|
提出日時 | 2022-07-18 15:56:30 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 4,422 ms / 6,000 ms |
コード長 | 5,207 bytes |
コンパイル時間 | 2,663 ms |
コンパイル使用メモリ | 212,956 KB |
最終ジャッジ日時 | 2025-01-30 10:53:01 |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 30 MLE * 14 |
ソースコード
#include<bits/stdc++.h>using namespace std;#define rep(i,n) for(ll i=0;i<n;i++)#define repl(i,l,r) for(ll i=(l);i<(r);i++)#define per(i,n) for(ll i=(n)-1;i>=0;i--)#define perl(i,r,l) for(ll i=r-1;i>=l;i--)#define fi first#define se second#define pb push_back#define ins insert#define pqueue(x) priority_queue<x,vector<x>,greater<x>>#define all(x) (x).begin(),(x).end()#define CST(x) cout<<fixed<<setprecision(x)#define rev(x) reverse(x);using ll=long long;using vl=vector<ll>;using vvl=vector<vector<ll>>;using pl=pair<ll,ll>;using vpl=vector<pl>;using vvpl=vector<vpl>;const ll MOD=1000000007;const ll MOD9=998244353;const int inf=1e9+10;const ll INF=4e18;const ll dy[8]={1,0,-1,0,1,1,-1,-1};const ll dx[8]={0,1,0,-1,1,-1,1,-1};template <typename T> inline bool chmax(T &a, T b) {return ((a < b) ? (a = b, true) : (false));}template <typename T> inline bool chmin(T &a, T b) {return ((a > b) ? (a = b, true) : (false));}//N=10^5,s<=10^10で1000msくらいstruct fast_factorize{using i128=__int128_t;vector<int> wit={2, 325, 9375, 28178, 450775, 9780504, 1795265022};ll modpow(ll a,ll b,ll m){ll ret=1,now=a;while(b){if(b&1)ret=i128(ret)*now%m;now=i128(now)*now%m;b>>=1;}return ret;}bool isprime(ll p){if(p==2)return true;if(p==1||p%2==0)return false;ll s=0,d=p-1;while(d%2==0){d/=2;s++;}for(auto a:wit){if(a%p==0)continue;bool iscomp=true;ll x=modpow(a,d,p);if(x==1)iscomp=false;rep(i,s){if(x==p-1)iscomp=false;x=i128(x)*x%p;}if(iscomp)return false;}return true;}long long find_factor(long long n) {assert(n > 1);if (n % 2 == 0) return 2;if (isprime(n)) return n;auto f = [&](__int128 x) -> long long { return (x * x + 1) % n; };for (int t = 1;; t++) {long long x0 = t, m = max(n >> 3, 1LL), x, ys, y = x0, r = 1, g, q = 1;do {x = y;for (int i = r; i--;) y = f(y);long long k = 0;do {ys = y;for (int i = min(m, r - k); i--;) y = f(y), q = __int128(q) * abs(x - y) % n;g = gcd(q, n);k += m;} while (k < r and g <= 1);r <<= 1;} while (g <= 1);if (g == n) {do {ys = f(ys);g = gcd(abs(x - ys), n);} while (g <= 1);}if (g != n) return g;}}vector<ll> factor(ll n){vector<ll> ret;while(n>1){ll f=find_factor(n);if(f<n){auto tmp=factor(f);ret.insert(ret.end(),all(tmp));}else ret.emplace_back(n);n/=f;}sort(all(ret));return ret;}};fast_factorize fz;ll modpow(ll a,ll n, ll mod) {if(n==0)return 1;a%=mod;if(a==0)return 0;ll res = 1;while (n > 0) {if (n & 1) res = res * a % mod;a = a * a % mod;n >>= 1;}return res;}random_device rd; mt19937 mt(rd());ll primitive_root(ll n){uniform_int_distribution<> rand(2,n-1);auto f=fz.factor(n-1);while(1){ll r=rand(mt);bool ok=true;for(auto q:f){if(modpow(r,(n-1)/q,n)==1)ok=false;}if(ok)return r;}}ll euler_phi(ll n) {ll ret = n;for(ll i = 2; i * i <= n; i++) {if(n % i == 0) {ret -= ret / i;while(n % i == 0) n /= i;}}if(n > 1) ret -= ret / n;return ret;}//中国剰余定理// 返り値: a と b の最大公約数// ax + by = gcd(a, b) を満たす (x, y) が格納されるlong long extGcd(long long a, long long b, long long &x, long long &y) {if (b == 0) { x = 1; y = 0; return a; }long long d = extGcd(b, a%b, y, x);y -= a/b * x;return d;}ll calc(ll a,ll e,ll m){//ax=e mod mを満たすxを探す、もしないなら-1ll g=gcd(a,m);if(e%g!=0)return -1;ll x,y;extGcd(a,m,x,y);x*=e/g;return ((x%m)+m)%m;}void solve(){ll p,k,a;cin >> p >> k >> a;if(p==2){cout << 1 << endl;return;}/*if(gcd(k,p-1)!=1){cout << -1 << endl;return;}*/ll e=0;ll r=primitive_root(p);{unordered_map<int,int> mp;ll now=1;for(int i=0;i<8000;i++){mp[now]=i;now=now*r%p;}ll ap=a;ll invnow=modpow(now,p-2,p);for(int i=0;i<125001;i++){if(mp.count(ap)){e=mp[ap]+i*8000;break;}ap=ap*invnow%p;}}//cout << r <<" " << e << endl;//if(modpow(r,e,p)!=a)cout <<"WA"<< endl;//x*k=e mod p-1 を求めるll x=calc(k,e,p-1);/*ll x=INF;{unordered_map<int,int> mp;ll now=0;for(int i=0;i<8000;i++){mp[now]=i;now+=k;if(now>=p-1)now-=p-1;}ll ap=e%(p-1);for(int i=0;i<125001;i++){if(mp.count(ap)){x=i*8000+mp[ap];break;}ap-=now;if(ap<0)ap+=p-1;}}//cout << x << endl;*/ll ans=modpow(r,x,p);if(modpow(ans,k,p)!=a)cout << -1 << endl;else cout << ans << endl;}int main(){ios::sync_with_stdio(false);std::cin.tie(nullptr);ll t;cin >> t;while(t--){solve();}}