暂无链接
整除
题目描述
整除符号为
∣
|
∣,
d
∣
n
d|n
d∣n 在计算机语言中可被描述为
n
%
d
=
=
0
n\%d == 0
n%d==0。
现有一算式
n
∣
x
m
−
x
n|x^m − x
n∣xm−x,给定
n
,
m
n,m
n,m,求
[
1
,
n
]
[1, n]
[1,n]以内
x
x
x解的个数。
解可能很大,输出取模
998244353
998244353
998244353。
格式
输入格式
其中
n
n
n的给定方式是由
c
c
c个不超过
t
t
t的质数的乘积给出的,
c
c
c和
t
t
t的范围会在数据范围中给出。
第一行一个
i
d
id
id表示这个数据点的标号。
多组数据,其中第二行一个整数
T
T
T表示数据组数。
对于每一组数据:
第一行两个整数
c
c
c和
m
m
m。
第二行
c
c
c个整数,这些整数都是质数,且两两不同,他们的乘积即为
n
n
n。
由于你可以通过输入求出
t
t
t,输入不再给出。
输出格式
对于每组数据输出一行,表示解的个数。
样例
样例输入
0
1
2 3
2 3
样例输出
6
另有两个样例,见下发文件。
数据范围
测试点 | c ≤ c ≤ c≤ | t ≤ t ≤ t≤ | m ≤ m ≤ m≤ | T ≤ T ≤ T≤ |
---|---|---|---|---|
1 1 1 | 2 2 2 | 1 0 3 10^3 103 | 2 2 2 | 50 50 50 |
2 2 2 | 2 2 2 | 1 0 3 10^3 103 | 1 0 9 10^9 109 | 50 50 50 |
3 3 3 | 2 2 2 | 1 0 2 10^2 102 | 10 10 10 | 10000 10000 10000 |
4 4 4 | 1 1 1 | 1 0 4 10^4 104 | 2 2 2 | 50 50 50 |
5 5 5 | 2 2 2 | 1 0 4 10^4 104 | 2 2 2 | 50 50 50 |
6 , 7 , 8 6,7,8 6,7,8 | 10 10 10 | 1 0 4 10^4 104 | 1 0 9 10^9 109 | 50 50 50 |
9 , 10 9,10 9,10 | 50 50 50 | 1 0 4 10^4 104 | 1 0 9 10^9 109 | 50 50 50 |
其中所有数据点都满足 1 ≤ c ≤ 50 , 1 ≤ t ≤ 1 0 4 , 1 ≤ m ≤ 1 0 9 , 1 ≤ T ≤ 10000 1 ≤ c ≤ 50,1 ≤ t ≤ 10^4,1 ≤ m ≤ 10^9,1 ≤ T ≤10000 1≤c≤50,1≤t≤104,1≤m≤109,1≤T≤10000。
题解
发现对于
n
∣
x
m
−
x
(
n
=
∏
p
i
)
n|x^m-x\ (n=\prod p_i)
n∣xm−x (n=∏pi)这个式子的求解,可以化为对下面这个方程组的求解:
{
x
m
−
x
≡
0
m
o
d
  
p
1
x
m
−
x
≡
0
m
o
d
  
p
2
⋮
x
m
−
x
≡
0
m
o
d
  
p
c
\left\{ \begin{aligned} &x^m-x\equiv 0\mod p_1\\ &x^m-x\equiv 0\mod p_2\\ &\qquad \vdots \\ &x^m-x\equiv 0\mod p_c\\ \end{aligned} \right.
⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧xm−x≡0modp1xm−x≡0modp2⋮xm−x≡0modpc
可以发现,这是一个同余方程组,那么根据中国剩余定理,整个方程组的解的个数便等于方程组中每个方程的解的个数的乘积,我们可以 O ( p ) O(p) O(p)的遍历 [ 1 , p ] [1,p] [1,p]的所有数来求解每个方程,再将解的个数乘起来得到答案,解决单词询问的复杂度为 O ( ∑ ( p i log p i ) ) O(\sum (p_i\log p_i)) O(∑(pilogpi))。
然而丧心病狂的出题人并不满足于这样的复杂度,复杂度瓶颈在于快速幂的 log p \log p logp,考虑我们实际上在处理函数 f ( x ) = x m m o d    p f(x)=x^m\mod p f(x)=xmmodp在 [ 1 , p ] [1,p] [1,p]内的值,这个函数是积性的,所以 f ( x ) f(x) f(x)在合数上的值可以线性筛出来,我们只需要在质数做快速幂,因为质数的个数约等于 p i log p i \frac{p_i}{\log p_i} logpipi,刚好与快速幂 log p i \log p_i logpi抵消,于是最后复杂度降为 O ( ∑ p i ) O(\sum p_i) O(∑pi)。
代码
#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();}