您的位置:首页 > 其它

[51nod 1594]Gcd and Phi

2016-12-12 22:13 393 查看

题目大意

求所有(i,j)满足1<=i<=n和1<=j<=n,phi(i)和phi(j)的gcd的欧拉函数值和。

数论题

挺简单的。

枚举gcd然后莫比乌斯反演一波。

接下来的式子中需要用到的均能够进行n log n预处理。

式子不太想写了, 可以看看代码。

#include<cstdio>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=2000000+10;
ll f[maxn],g[maxn];
int mu[maxn],pri[maxn],phi[maxn],num[maxn],cnt[maxn];
bool bz[maxn];
int i,j,k,l,t,n,m,top,ca;
ll ans;
int main(){
mu[1]=phi[1]=1;
fo(i,2,maxn-10){
if (!bz[i]){
pri[++top]=i;
mu[i]=-1;
phi[i]=i-1;
}
fo(j,1,top){
if ((ll)i*pri[j]>maxn-10) break;
bz[i*pri[j]]=1;
if (i%pri[j]==0){
mu[i*pri[j]]=0;
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
mu[i*pri[j]]=-mu[i];
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
scanf("%d",&ca);
while (ca--){
scanf("%d",&n);
fo(i,1,n) cnt[i]=num[i]=f[i]=g[i]=0;
fo(i,1,n) num[phi[i]]++;
fo(i,1,n)
fo(j,1,n/i)
cnt[i]+=num[i*j];
fo(i,1,n) g[i]=(ll)cnt[i]*cnt[i];
fo(i,1,n)
fo(j,1,n/i)
f[i]+=g[i*j]*mu[j];
ans=0;
fo(i,1,n) ans+=(ll)phi[i]*f[i];
printf("%lld\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: