HDU 5212 - Code

CodeForces 839D - Winter is here 可以说是一模一样了

/*
HDU 5212 - Code [ 容斥 ]
题意:
	求 ∑ [1<=i,j<=n] gcd(a[i], a[j]) * (gcd(a[i], a[j])-1)
分析:
	改用权值数组num[i] 记录 i 的倍数的个数, sum[i] 为 gcd(a,b) >= i 的 (a,b) 对
	然后按容斥减去 i 的倍数 sum[j] 对 sum[i] 的影响,使得 sum[i] 最终等于 gcd(a,b) == i 的 (a,b) 对
	复杂度 O(nlogn)
*/
#include <bits/stdc++.h>
using namespace std;
const int MOD = 10007;
const int N = 1e4+5;
int n, num[N], Max, sum[N];
int main()
{
    while (~scanf("%d", &n))
    {
        memset(num, 0, sizeof(num));
        Max = 0;
        for (int i = 1; i <= n; i++)
        {
            int x; scanf("%d", &x);
            num[x]++;
            Max = max(Max, x);
        }
        for (int i = 1; i <= Max; i++)
            for (int j = i+i; j <= Max; j += i)
                num[i] += num[j];
        int ans = 0;
        for (int i = Max; i >= 1; i--)
        {
            sum[i] = 1LL * num[i]*num[i] % MOD;
            for (int j = i+i; j <= Max; j += i)
                sum[i] = (sum[i] - sum[j] + MOD) % MOD;
            ans = (ans + 1LL * sum[i] * i*(i-1) % MOD) % MOD;
        }
        printf("%d\n", ans);
    }
}

  

posted @ 2017-08-14 22:49  nicetomeetu  阅读(147)  评论(0编辑  收藏  举报