zoukankan      html  css  js  c++  java
  • 公约数

    公约数

    问n个数的所有子集的gcd和。(1 le n le 1000000)

    首先想的是一个二维dp【可怜】

    正解是对于一个公约数x,统计出gcd正好是它的子集个数f[x]。可以用容斥来搞。

    具体来说,gcd正好是x的子集个数就是(2^{x的倍数的个数}-f[kx])

    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    typedef long long LL;
    const int maxn=1e6+5, mod=1e9+7;
    int f[maxn], a[maxn], c[maxn];
    int fpow(int a, int x){
        LL base=a, ans=1;
        for (; x; x>>=1, (base*=base)%=mod)
            if (x&1) (ans*=base)%=mod;
        return ans;
    }
    int n, m, ans;
    int main(){
        scanf("%d%d", &n, &m);
        for (int i=1; i<=n; ++i){
            scanf("%d", &a[i]);
            ++c[a[i]]; }
        int cnt=0;
        for (int i=m; i>0; --i){
            cnt=0;
            for (int j=i; j<=m; j+=i){
                cnt+=c[j];
                f[i]+=mod-f[j]; f[i]%=mod;
            }
            f[i]+=fpow(2, cnt)-1; f[i]%=mod;
            ans+=(1ll*f[i]*i)%mod; ans%=mod;
        }
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    NYOJ 10 skiing DFS+DP
    51nod 1270 数组的最大代价
    HDU 4635 Strongly connected
    HDU 4612 Warm up
    POJ 3177 Redundant Paths
    HDU 1629 迷宫城堡
    uva 796
    uva 315
    POJ 3180 The Cow Prom
    POJ 1236 Network of Schools
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/9747544.html
Copyright © 2011-2022 走看看