题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6265
题意:已知欧拉函数为φ(n),有公式如下:
其中p是n的所有互不相同的素因子。然后给出n,求如下函数:
其中n是以分解质因子的形式给出,即对于n=p1^q1*p2^q2...*pm^qm,题目先给出m,再接着m行每行给出pi,qi。
解析:
对于给出的n,d的每个因子,将其带入公式
中有:
考虑n的因子d=p1^1,它对答案的贡献为:n*(1-1/p1)
考虑n的因子d=p1^2,它对答案的贡献为:n*(1-1/p1)
。。。。。。
考虑n的因子d=p1^q1,它对答案的贡献为:n*(1-1/p1)
那么对于单个素因子p1它对答案的贡献为:n*(1-1/p1)*q1
同样对于单个素因子pk它对答案的贡献为:n*(1-1/pk)*qk
考虑n的因子d=p1^1*p2^1,它对答案的贡献为:n*(1-1/p1)*(1-1/p2)
考虑n的因子d=p1^1*p2^2,它对答案的贡献为:n*(1-1/p1)*(1-1/p2)
。。。。。。
考虑n的因子d=p1^q1*p2^q2,它对答案的贡献为:n*(1-1/p1)*(1-1/p2)
那么对于两个素因子p1,p2它对答案的贡献为:n*(1-1/p1)*(1-1/p2)*q1*q2
同样对于两个素因子pi,pj它对答案的贡献为:n*(1-1/pi)*(1-1/pj)*qi*qj
。。。。。。
显然对于一个d只要其包含的素因子相同,那么它对答案的贡献就一样,假设d包含素因子p1~pk,显然这样的d有q1*q2...*qk个,它对答案的贡献为:
那么对于此题,我们只需dfs枚举m个素因子在或不在的2^m种情况,就是不同的d的种类数,然后统计答案即可。
代码O(2^m*20)(171ms):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll m,ans,n,a,all,j,k,p[30],q[30],tt[30];
ll fpow(ll n,ll k)//快速幂求n^k
{
ll res=1;
n=n%mod;
while(k>0)
{
if(k&1)
res=res*n%mod;
n=n*n%mod;
k>>=1;
}
return res;
}
void init(int m)//不进行此预处理也会超时
{
for(int k=1;k<=m;k++)//tt[i]是素因子p[i]的贡献
{
tt[k]=q[k]*(p[k]-1)%mod*fpow(p[k],mod-2)%mod;
}
}
void dfs(int step,ll tmp)//枚举p[step]的状态
{
if(step>m)
{
ans=(ans+n*tmp)%mod;
return;
}
dfs(step+1,tmp*tt[step]%mod);
dfs(step+1,tmp);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&m);
n=1;
for(int i=1;i<=m;i++)
{
scanf("%lld%lld",&p[i],&q[i]);
n=n*fpow(p[i],q[i])%mod;
}
init(m);
ans=0;
dfs(1,1);
//ans=(ans+n)%mod;
printf("%lld\n",ans);
}
return 0;
}