BZOJ 2005 2005: [Noi2010]能量采集 | 容斥原理
题目:
http://www.lydsy.com/JudgeOnline/problem.php?id=2005
题解:
http://blog.csdn.net/popoqqq/article/details/39924877
#include<cstdio> #include<algorithm> #define N 100005 using namespace std; typedef long long ll; ll phi[N],su[N],sum[N]; bool he[N]; void Euler(int n) { int tot=0; phi[1]=1; for(int i=2;i<=n;i++) { if(!he[i]) { su[++tot]=i; phi[i]=i-1; } for(int j=1;j<=tot;j++) { if(i*su[j]>=n)break; he[i*su[j]]=1; if(i%su[j]==0) { phi[i*su[j]]=phi[i]*su[j];break; } else phi[i*su[j]]=phi[i]*(su[j]-1); } } for(int i=1;i<=n;i++) phi[i]+=phi[i-1]; return; } int main(){ ll n,m,ans=0; scanf("%lld%lld",&n,&m); if(n>m)swap(n,m); Euler(n+1); for(ll i=1,j;i<=n;i=j+1) { j=min(n/(n/i),m/(m/i)); ans+=(ll)(phi[j]-phi[i-1])*(n/i)*(m/i); } printf("%lld\n",2*ans-n*m); return 0; }