zoukankan      html  css  js  c++  java
  • CodeForces 839D

    赛后听 Forever97 讲的思路,强的一匹- -

    /*
    CodeForces 839D - Winter is here [ 数论,容斥 ] | Codeforces Round #428 (Div. 2)
    题意:
    	给出数列a[N]
    	对每个子集,若 gcd(a[I1], a[I2], a[I3] ..., a[In]) > 1,则贡献为 n*gcd
    	求总贡献和
    	限制: N <= 2e5,a[i] <= 1e6
    分析:
    	记录 num[i]数组为 i 的倍数的个数
    	则 gcd >= i 能组成的所有方案的总人数 f(i) = 2^(num[i]-1)*num[i]
    	设 g(i) 为 gcd == i 能组成的所有方案的总人数 
    	可得 f(x) = ∑ [x|y] g(y)  
    	反演或者容斥即可
    */
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int N = 1e6+5;
    const LL MOD = 1e9+7;
    int n, a[N], num[N], Max;
    LL two[N], sum[N];
    int main()
    {
        two[0] = 1;
        for (int i = 1; i < N; i++) two[i] = two[i-1] * 2 % MOD;
        scanf("%d", &n);
        Max = 0;
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            Max = max(a[i], Max);
            num[a[i]]++;
        }
        for (int i = 1; i <= Max; i++)
            for (int j = i+i; j <= Max; j += i)
                num[i] += num[j];
        LL ans = 0;
        for (int i = Max; i >= 2; i--)
        {
            sum[i] = two[num[i]-1]*num[i] % MOD;
            for (int j = i+i; j <= Max; j += i)
            {
                sum[i] = (sum[i] - sum[j] + MOD) % MOD;
            }
            ans = (ans + sum[i] * i % MOD) % MOD;
        }
        printf("%lld
    ", ans);
    }
    

    比赛时候写的很随意- -,不过思路是一样的

    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    const LL MOD = 1e9+7;
    const int N = 1000005;
    bool notp[N];
    int prime[N], pnum, mu[N];
    void Mobius() {
    	memset(notp, 0, sizeof(notp));
    	mu[1] = 1;
    	for (int i = 2; i < N; i++) {
    		if (!notp[i]) prime[++pnum] = i, mu[i] = -1;
    		for (int j = 1; prime[j]*i < N; j++) {
    			notp[prime[j]*i] = 1;
    			if (i%prime[j] == 0) {
    				mu[prime[j]*i] = 0;
    				break;
    			}
    			mu[prime[j]*i] = -mu[i];
    		}
    	}
    }
    int n, a[N], Max;
    int num[N];
    LL two[N];
    int main()
    {
        two[0] = 1;
        for (int i = 1; i < N; i++) two[i] = two[i-1]*2 % MOD;
        Mobius();
        scanf("%d", &n);
        Max = 0;
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            Max = max(Max, a[i]);
            for (LL j = 1; j*j <= a[i]; j++)
            {
                if (j*j == a[i]) num[j]++;
                else if (a[i] % j == 0)
                    num[j]++, num[a[i]/j]++;
            }
        }
        LL ans = 0;
        for (int i = 2; i <= Max; i++)
        {
            LL sum = 0;
            for (int j = i, k = 1; j <= Max; j += i, k++)
            {
                sum += (mu[k] * (two[num[j]-1]*num[j])%MOD + MOD) % MOD;
                sum %= MOD;
            }
            ans = (ans + sum * i%MOD) % MOD;
        }
        printf("%lld
    ", ans% MOD);
    }
    

      

  • 相关阅读:
    在数组中寻找和为定值的n个数
    第九届蓝桥杯省赛第六题---递增三元组
    序列螺旋矩阵
    铁轨
    最长公共子串
    STL之vector,deque学习实例
    jdbc Date问题(util.Date和sql.Date)DatePreparedStatement.set
    inti-mothd
    获取HttpResponse并解析JSON数据
    could not find the main class,program will exit
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/7353662.html
Copyright © 2011-2022 走看看