暫無鏈接
整除
題目描述
整除符號爲, 在計算機語言中可被描述爲 。
現有一算式,給定,求以內解的個數。
解可能很大,輸出取模。
格式
輸入格式
其中的給定方式是由個不超過的質數的乘積給出的,和的範圍會在數據範圍中給出。
第一行一個表示這個數據點的標號。
多組數據,其中第二行一個整數表示數據組數。
對於每一組數據:
第一行兩個整數和。
第二行個整數,這些整數都是質數,且兩兩不同,他們的乘積即爲。
由於你可以通過輸入求出,輸入不再給出。
輸出格式
對於每組數據輸出一行,表示解的個數。
樣例
樣例輸入
0
1
2 3
2 3
樣例輸出
6
另有兩個樣例,見下發文件。
數據範圍
測試點 | ||||
---|---|---|---|---|
其中所有數據點都滿足。
題解
發現對於這個式子的求解,可以化爲對下面這個方程組的求解:
可以發現,這是一個同餘方程組,那麼根據中國剩餘定理,整個方程組的解的個數便等於方程組中每個方程的解的個數的乘積,我們可以的遍歷的所有數來求解每個方程,再將解的個數乘起來得到答案,解決單詞詢問的複雜度爲。
然而喪心病狂的出題人並不滿足於這樣的複雜度,複雜度瓶頸在於快速冪的,考慮我們實際上在處理函數在內的值,這個函數是積性的,所以在合數上的值可以線性篩出來,我們只需要在質數做快速冪,因爲質數的個數約等於,剛好與快速冪抵消,於是最後複雜度降爲。
代碼
#include<bits/stdc++.h>
using namespace std;
const int M=1e4+5,mod=998244353;
int p[M/3],f[M],sum[M],c,m,T,ans,i,a;
bool vis[M];
int power(int x,int p,int mod){int r=1;for(;p;p>>=1,x=x*x%mod)if(p&1)r=r*x%mod;return r;}
int sie(int n,int m)
{
int i=2,ans=2,t;
for(p[0]=0;i<n;++i)
{
if(!vis[i])p[++p[0]]=i,f[i]=power(i,m,n);
for(int j=1;j<=p[0];++j){if((t=i*p[j])>n)break;vis[t]=1;f[t]=f[i]*f[p[j]]%n;if(i%p[j]==0)break;}
ans+=f[i]==i;
}
return ans;
}
void in(){scanf("%d%d",&c,&m);}
void ac(){for(ans=i=1;i<=c;++i)scanf("%d",&a),ans=1ll*ans*sie(a,m)%mod;printf("%d\n",ans);}
int main(){for(scanf("%*d%d",&T);T--;)in(),ac();}