zoukankan      html  css  js  c++  java
  • Codeforces #428 Div2 D

    #428 Div2 D

    题意

    给出一些数,现在要求找出一些数满足 (i_1 < i_2 < i_3 < ... < i_k) 以及 (gcd(a_{i_1}, a_{i_2}, ..., a_{i_k}) > 1) ,记这些数的贡献为 (k * gcd(a_{i_1}, a_{i_2}, ..., a_{i_k}) )
    求每种方案的贡献之和。

    分析

    不得不说和 hdu6053 很类似,其实还要简单不少。

    考虑枚举 (gcd) ,我们可以找到因子有 (gcd) 这个数的数有多少个,假设有因子 (2) 的数有 (x) 个,那么这些数的贡献就是 (2 * (1*C_{x}^{1}+2*C_{x}^{2}+..+x*C_{x}^{x})) (通过打表可以发现规律),但是在枚举因子 (2) 的时候可能会把 (2) 的倍数作为因子形成的方案也考虑了,通过容斥去处理得到最后结果。

    这里容斥类似于筛法的思想,实现和理解都更简单。

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 2e5 + 10;
    const int N = 1e6 + 10;
    const int MOD = 1e9 + 7;
    ll num[MAXN];
    int a[N];
    ll has[N];
    int main() {
        ll e = 1;
        for(int i = 1; i < MAXN; i++) {
            num[i] = (num[i - 1] * 2 + e) % MOD;
            e = e * 2 % MOD;
        }
        int n;
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            int x;
            scanf("%d", &x);
            a[x]++;
        }
        ll ans = 0;
        for(int i = N - 1; i >= 2; i--) {
            int s = 0;
            for(int j = i; j < N; j += i) {
                s += a[j];
            }
            has[i] = num[s];
            for(int j = 2 * i; j < N; j += i) {
                has[i] = (has[i] - has[j] + MOD) % MOD;
            }
            ans = (ans + 1LL * i * has[i]) % MOD;
        }
        printf("%I64d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    Java HttpClient使用小结
    【剑指offer】Q18:树的子结构
    poj3041-Asteroids , 二分图的最小顶点覆盖数 = 最大匹配数
    jquery.validate+jquery.form提交的三种方式
    &quot;undefined reference to&quot; 问题解决方法
    [Oracle]
    Effective_java之二:慎用重载函数
    C99规范
    迭代、递归替代循环
    1)Linux程序设计入门--基础知识
  • 原文地址:https://www.cnblogs.com/ftae/p/7360437.html
Copyright © 2011-2022 走看看