题解 P10580
HYdroKomide · · 题解
题意:
给定一个数列的元素个数
思路:
不难发现数列中所有元素必然为
设
对于
使用容斥思想。先考虑没有限制的情况,
接着,要减去所有被限制的情况。为了满足最大公约数的条件,至少需要有一个元素
最后,注意到指数全部在
因此,对于质因子
观察到
易错点:取模运算相减后可能导致出现负数,需要在输出时对模数相加。
程序如下:
#include<cstdio>
#include<cstring>
using namespace std;
const int N=35,MOD=998244353;
int q,cnt,p[N],k[N];
void getprime(int x){//分解质因数
cnt=0;
for(int i=2;i*i<=x;i++){
if(x%i==0){
k[++cnt]=0;//提前清空
while(x%i==0){
x/=i;
k[cnt]++;
}
}
}
if(x!=1)k[++cnt]=1;//注意如果没分解完,说明剩下的是单独的一个质数
}
long long qpow(long long x,long long y){
long long ret=1;
while(y){
if(y&1)ret=ret*x%MOD;
y>>=1;
x=x*x%MOD;
}
return ret;
}
int main(){
scanf("%d",&q);
while(q--){
int x,y,n;
long long ans=1;
scanf("%d%d%d",&x,&y,&n);
getprime(y/x);
for(int i=1;i<=cnt;i++){
long long tmp=qpow(k[i]+1,n);
tmp=(tmp-qpow(k[i],n))%MOD;
tmp=(tmp-qpow(k[i],n))%MOD;
tmp=(tmp+qpow(k[i]-1,n))%MOD;
tmp=(tmp+MOD)%MOD;
ans=ans*tmp%MOD;
}
printf("%lld\n",(ans+MOD)%MOD);//注意再加一次模数,防止出负
}
return 0;
}