結果
| 問題 |
No.981 一般冪乗根
|
| ユーザー |
tko919
|
| 提出日時 | 2020-04-08 18:44:26 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 14 ms / 6,000 ms |
| コード長 | 2,171 bytes |
| コンパイル時間 | 3,582 ms |
| コンパイル使用メモリ | 176,932 KB |
| 実行使用メモリ | 5,376 KB |
| 最終ジャッジ日時 | 2024-07-19 03:55:06 |
| 合計ジャッジ時間 | 39,143 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 30 WA * 14 |
ソースコード
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
//template
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(a);i>(b);i--)
#define ALL(v) (v).begin(),(v).end()
typedef long long int ll;
const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; const double eps=1e-12;
void tostr(ll x,string& res){while(x)res+=('0'+(x%10)),x/=10; reverse(ALL(res)); return;}
template<class T> inline bool chmax(T& a,T b){ if(a<b){a=b;return 1;}return 0; }
template<class T> inline bool chmin(T& a,T b){ if(a>b){a=b;return 1;}return 0; }
//end
ll mpow(ll x,ll k,ll m){
ll res=1;
while(k){
if(k&1)res=(res*x)%m;
x=(x*x)%m; k>>=1;
} return res;
}
ll inv(ll a,ll m){
ll b=m,u=1,v=0;
while(b){
ll t=a/b;
a-=t*b; swap(a,b);
u-=t*v; swap(u,v);
}
u%=m; if(u<0)u+=m; return u;
}
ll sub_root(ll p,int e,ll a,ll m){//x^(p^e)==a(mod m)
ll q=m-1; int s=0; while(q%p==0){q/=p; s++;} int d=s-e;
ll pe=mpow(p,e,m),res=mpow(a,((pe-1)*inv(q,pe)%pe*q+1)/pe,m),c=1;
while(mpow(c,(m-1)/p,m)==1)c++; c=mpow(c,q,m);
map<ll,ll> mp; ll v=1,block=sqrt(d*p)+1,bs=mpow(c,mpow(p,s-1,m-1)*block%(m-1),m);
rep(i,0,block+1)mp[v]=i,v=v*bs%m;
ll gs=inv(mpow(c,mpow(p,s-1,m-1),m),m);
cerr<<res<<endl;
rep(i,0,d){
ll err=a*inv(mpow(res,pe,m),m)%m;
ll pos=mpow(err,mpow(p,d-1-i,m-1),m);
rep(j,0,block+1){
if(mp.count(pos)){
res=res*mpow(c,(block*mp[pos]+j)*mpow(p,i,m-1)%(m-1),m)%m;
break;
} pos=pos*gs%m;
}
} return res;
}
ll mod_root(ll k,ll a,ll m){
if(a==0)return k?0:-1;
if(m==2)return a&1;
k%=m-1; ll g=__gcd(k,m-1);
if(mpow(a,(m-1)/g,m)!=1)return -1;
a=mpow(a,inv(k/g,(m-1)/g),m);
for(ll d=2;d*d<=g;d++)if(g%d==0){
int sz=0;
while(g%d==0){g/=d; sz++;}
a=sub_root(d,sz,a,m);
}
if(g>1)a=sub_root(g,1,a,m); return a;
}
int main(){
int q; cin>>q;
while(q--){
ll k,a,m; scanf("%lld%lld%lld",&m,&k,&a);
ll res=mod_root(k,a,m); printf("%lld\n",res);
//if(res!=-1 and mpow(res,k,m)!=a)cerr<<"-----------------------------------"<<endl;
}
return 0;
}
tko919