在ACM_DIY群中,有一位叫做“傻崽”的同学由于在数论方面造诣很高,被称为数轮之神!对于任何数论问题,他都能瞬间秒杀! 一天他在群里面问了一个神题:对于给定的
3
3
3个非负整数
A
,
B
,
K
A,B,K
A,B,K 求出满足
(
1
)
X
A
=
B
(
m
o
d
2
∗
K
+
1
)
(1) X^A= B(mod 2*K + 1)
(1)XA=B(mod2∗K+1)
(
2
)
X
(2) X
(2)X在范围
[
0
,
2
K
]
[0, 2K]
[0,2K]内
的
X
X
X的个数!
这个题解明明超详细却打错了一两个公式
有点数论大礼包的感觉。
#include<bits/stdc++.h>
using namespace std;
map<int,int>mp;
int p[20],c[20];
int gcd(int a,int b){ return !b ? a : gcd(b,a%b); }
int Pow(int base,int k){
int ret = 1;
for(;k;k>>=1,base=base*base)
if(k&1)
ret=ret*base;
return ret;
}
int Pow(int base,int k,int p){
int ret = 1;
for(;k;k>>=1,base=1ll*base*base%p)
if(k&1)
ret=1ll*ret*base%p;
return ret;
}
int Getg(int P,int phi){
static int p[20];
p[0] = 0;
int u = phi;
for(int i=2;i*i<=u;i++)
if(u%i==0){
p[++p[0]] = phi / i;
for(;u%i==0;u/=i);
}
if(u>1) p[++p[0]] = phi/u;
for(int r=2;;r++) if(gcd(r,P)==1){
bool flg = 0;
for(int i=1;i<=p[0];i++)
if(Pow(r,p[i],P) == 1)
{ flg = 1; break; }
if(!flg) return r;
}
}
int main(){
int T;
for(scanf("%d",&T);T--;){
p[0] = 0;
int A,B,C;
scanf("%d%d%d",&A,&B,&C);C=C*2+1;
for(int i=2;i*i<=C;i++)
if(C%i==0){
p[++p[0]] = i , c[p[0]] = 0;
for(;C%i==0;C/=i,c[p[0]]++);
}
if(C>1) p[++p[0]]=C,c[p[0]]=1;
int ans = 1;
for(int i=1;i<=p[0];i++){
int t = gcd(B,Pow(p[i],c[i])) , ct = 0;
if(t == Pow(p[i],c[i])){ ans = 1ll * ans * Pow(p[i],c[i]-ceil(c[i]*1.0/A)); continue; }
for(int u=t;u>1;u/=p[i],ct++);
if(ct % A){ ans = 0; break; }
int P = Pow(p[i],c[i]-ct) , b = (B / t) % P , g = Getg(P,P/p[i]*(p[i]-1)) , c = 1 , d = 1 , M = ceil(sqrt(P/p[i]*(p[i]-1)));
mp.clear();
for(int j=1;j<=M;j++) c = 1ll * c * g % P,mp[1ll * c * b % P]=j;
for(int j=1;j<=M+1;j++){
d = 1ll * d * c % P;
if(mp.count(d)){ b=j*M-mp[d];break; }
}
int e = gcd(A,P/p[i]*(p[i]-1));
if(b % e){ ans=0;break; }
ans = ans * e * Pow(p[i],ct-ct/A);
}
printf("%d\n",ans);
}
}