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;
}

 

posted @ 2018-01-05 15:47  MSPqwq  阅读(...)  评论(...编辑  收藏