bzoj2818: Gcd

来源:互联网 发布:ubuntu查看64位 32位 编辑:程序博客网 时间:2024/05/29 07:15

求一遍欧拉函数前缀和,直接就可以O(n)解决。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;bool check[10000005];int prime[3000005],fai[10000005],tot;long long s[10000005];int main(){    int n;    cin>>n;    for(int i=2;i<=n;i++)    {        if(!check[i])        {            prime[tot++]=i;            fai[i]=i-1;        }        for(int j=0;j<tot;j++)        {            if(i*prime[j]>n)            break;            check[i*prime[j]]=1;            if(i%prime[j])            {                fai[i*prime[j]]=fai[i]*(prime[j]-1);            }            else            {                fai[i*prime[j]]=fai[i]*prime[j];                break;            }        }    }    fai[1]=1;    for(int i=1;i<=n;i++)    {        s[i]=s[i-1]+fai[i];    }    long long ans=0;    for(int i=0;i<tot;i++)    {        ans+=(s[n/prime[i]]<<1)-1;    }    cout<<ans;}