CF——Codeforces Round #428 (Div. 2)D. Winter is here

来源:互联网 发布:网络营销策划公司 编辑:程序博客网 时间:2024/05/22 13:56

D. Winter is here

题解

1.分别统计a[n]中2-n的倍数的个数b[n],设c[n] = 2^(b[n]-1)-1;
2.GCD=i的组合个数 = c[i] - ∑c[j](j为i的倍数)(推导过程略)
3.ANS = ∑a[i](a[i]≠1) + ∑(GCD=i的组合个数 )(i≠1)

AC code

#include<bits/stdc++.h>#define maxn 1000000 + 10const int  MOD =  1000000000 + 7;typedef long long LL;using namespace std;LL ans=0;LL cnt[maxn];LL a[maxn];LL p[maxn];void init(){    LL k = 1;    p[0] = 1;    for(int i = 1; i < maxn; i++)    {           p[i] = (p[i-1]*2);                p[i] = p[i] % MOD;    }//  cout << p[0] << " " << p[1] << " " << p[2] << endl;}   LL GCD(LL a,LL b){    if(b == 0) return a;    else return GCD(b,a%b);}int main(){    int n;    cin >> n;    init();    memset(a,0,sizeof(a));    memset(cnt,0,sizeof(cnt));    for(int i = 0; i < n; i++)    {        int e;        scanf("%I64d",&e);        a[e]++;        if(e>1) ans += e;        ans %= MOD;    }    for(int i = 2; i <= 1000000; i++)    {        for(int j = i; j <= 1000000;j+=i)        {            cnt[i] += a[j];        }    //  if(cnt[i]) cout << cnt[i] << " " << p[cnt[i]-1] << endl;        if(cnt[i])            cnt[i] = (p[cnt[i]-1]-1)*cnt[i]%MOD;    //  if(cnt[i]) cout << i << " " << cnt[i] << endl;    }    for(int i = 1000000; i >= 2; i--)    {        if(cnt[i] == 0) continue;        for(int j = 2*i; j <= 1000000; j+=i)        {            cnt[i] -= cnt[j];            cnt[i] = (cnt[i] + MOD)%MOD;        }        ans += cnt[i]*i;        ans %= MOD;    }    cout << ans%MOD << endl;    return 0;}
阅读全文
0 0