zoukankan      html  css  js  c++  java
  • Codeforces839D Winter is here 容斥

    /**
    题目:Codeforces839D Winter is here
    链接:http://codeforces.com/contest/839/problem/D
    题意:给定n个数,求所有的最大公约数>1的子集的贡献之和。
    一个子集的贡献为最大公约数*子集大小
    思路:
    cnt[i]表示约数为i的数的个数。
    ans[i]表示约数为i的所有k的和。
    
    已知ans[i]可以求得贡献为i*ans[i];
    
    cnt[i]个数的长度为(sigma(k))cnt[i]*(2^(cnt[i]-1)); 即所有子集长度的和。
    但是其中有些子集的gcd不是等于i。所以要减去。
    逆序枚举,ans[i] = cnt[i]*(2^(cnt[i]-1)) - sigma(ans[j]);(j%i==0&&j/i>1)
    
    */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <iostream>
    #include <vector>
    using namespace std;
    typedef long long LL;
    #define ms(x,y) memset(x,y,sizeof x)
    typedef pair<int, int> P;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const int maxn = 1e6 + 100;
    int cnt[maxn];
    int sum[maxn];
    LL ans[maxn];
    LL Pow(LL x, int y)
    {
        LL p = 1;
        while (y)
        {
            if (y & 1) p = p*x%mod;
            x = x*x%mod;
            y >>= 1;
        }
        return p;
    }
    int main()
    {
        int T, cas = 1;
        int n;
        while (scanf("%d",&n)==1)
        {
            int x, mas = 0;
            ms(cnt,0);
            ms(sum,0);
            ms(ans,0);
            for(int i = 1; i <= n; i++){
                scanf("%d",&x);
                mas = max(mas,x);
                sum[x]++;
            }
            for(int i = 2; i < maxn; i++){
                for(int j = i; j < maxn; j+=i){
                    cnt[i] += sum[j];
                }
            }
            LL res = 0;
            for(int i = mas; i >= 2; i--){
                if(cnt[i]==0) continue;
                LL num = 0;
                for(int j = 2*i; j <= mas; j+=i){
                    num = (num+ans[j])%mod;
                }
                ans[i] = (cnt[i]*Pow(2,cnt[i]-1)%mod-num+mod)%mod;
                res = (res+ans[i]*i%mod)%mod;
            }
            printf("%I64d
    ",res);
        }
    
        return 0;
    }
  • 相关阅读:
    HTTP断点续传 规格严格
    Java Shutdown 规格严格
    linux 命令源码 规格严格
    JTable调整列宽 规格严格
    linux 多CPU 规格严格
    Hello can not find git path 规格严格
    Kill 规格严格
    拜拜牛人 规格严格
    Swing 规格严格
    Debugging hangs in JVM (on AIX but methodology applicable to other platforms) 规格严格
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7356919.html
Copyright © 2011-2022 走看看