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;
    }
    
  • 相关阅读:
    命令[46]
    命令[53]
    命令[48]
    命令[43]
    命令[52]
    命令[55]
    命令[41]
    MYSQL[02]大小写问题
    hdu 1811
    hdu 1829
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/9747544.html
Copyright © 2011-2022 走看看