BZOJ 4804

http://www.lydsy.com/JudgeOnline/problem.php?id=4804

可以反演成Σ(i=1,n)(Σ(j,j|i)μ(j)*Φ(i/j))*[n/i]*[n/i]

过程略

设f(i)=Σ(j,j|i)μ(j)*Φ(i/j)

f就是μ和Φ的卷积

μ,Φ都是积性函数

那么f也是积性函数

可以线筛

对于f(y)

1.当y只有一种质因子时 f(y)=Φ(y)-Φ(y/prime)

2.当y有多于两中质因子时 当 gcd(a,b)=1 f(a*b)=f(a)*f(b)

#include<cstdio>
typedef long long ll;
const int N=1e7+11,maxn=1e7;
bool ip[N];
int pr[N];
int phi[N],f[N];
ll sum[N];
ll ans;
inline void shai_fa(){
	phi[1]=f[1]=1;sum[1]=1ll;
	for(register int i=2,l,k;i<=maxn;++i){
		if(!ip[i]){
			phi[pr[++pr[0]]=i]=i-1;
			f[i]=i-2;
		}
		for(register int j=1;j<=pr[0]&&i*pr[j]<=maxn;++j){
			ip[pr[j]*i]=1;
			if(i%pr[j]==0){	
				phi[i*pr[j]]=phi[i]*pr[j];
				l=i;
				k=pr[j];
				while(l%pr[j]==0){
					l/=pr[j];
					k*=pr[j];
				} 
				l!=1?f[i*pr[j]]=f[l]*f[k]:f[i*pr[j]]=phi[i*pr[j]]-phi[i];
				break;
			} 
			phi[i*pr[j]]=phi[i]*phi[pr[j]];
			f[i*pr[j]]=f[i]*f[pr[j]];
		}
		sum[i]=sum[i-1]+1ll*f[i];
	}
}
int n,T,pos;
int main(){
	shai_fa();
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		ans=0;
		for(register int i=1;i<=n;i=pos+1){
			pos=n/(n/i);
			ans+=1ll*(sum[pos]-sum[i-1])*(n/i)*(n/i);
		}
		printf("%lld\n",ans);
	}
	return 0;
}

 

posted @ 2017-12-14 09:57  Stump  阅读(186)  评论(0编辑  收藏  举报