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;
    }
  • 相关阅读:
    关闭弹出窗体,刷新父页面
    Oracle 导出部分表结构,以及导入
    ORCLE报错解决(ora01747:无效的用户.表.列,表.列)
    PL/SQL Developer使用技巧
    自定义table
    Array查询数组中是否包含指定字符
    水晶报表去掉多余小数点
    HttpHandler HttpModule入门篇
    窗口类名无效 错误 解决方法
    2020.10.15
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7356919.html
Copyright © 2011-2022 走看看