首先虽然题上没有说,但是可以当成保证有解来做,省掉很多麻烦的判断。
不妨记
2k+1=P
,
P=∏pdii
,
pi
是质数。对每一个
pdii
单独求解
xA≡B(modpdii)
的解的个数,因为每个方程得到的解都形如
x≡w(modpdii)
,从每个方程中任选一个解都能通过中国剩余定理求出模
P
下的通解,因此只需要把这些解的个数乘起来就行了。
接下来考虑如何求解
首先,如果
B=0
,也就是
xA
是
pd
的倍数,这样
x
一定是
否则的话,
B
可以写成
#include<cstdio>
#include<cmath>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
int A,b;
int pow(int base,int k)
{
int ret=1;
for (;k;k>>=1,base*=base)
if (k&1) ret*=base;
return ret;
}
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int solve(int p,int d,int pd)
{
int B=b%pd,f=1,a=0,k,phi,rt,ind,g;
if (B==0) return pow(p,d-(d+A-1)/A);
while (B%p==0)
{
B/=p;
d--;
pd/=p;
a++;
}
k=a/A;
phi=pd/p*(p-1);
g=gcd(A,phi);
return g*pow(p,a-k);
}
void solve()
{
int k,p,m,d,ans=1,pd;
scanf("%d%d%d",&A,&b,&k);
p=2*k+1;
m=sqrt(p+0.5);
for (int i=2;i<=m;i++)
if (p%i==0)
{
d=0;
pd=1;
while (p%i==0)
{
d++;
p/=i;
pd*=i;
}
ans*=solve(i,d,pd);
}
if (p>1) ans*=solve(p,1,p);
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while (T--) solve();
}