hdu 5212(容斥)

hdu 5212(容斥)

参考http://blog.csdn.net/lyhvoyage/article/details/45306211

题目大意:给出n个数,求gcd(a[i], a[j]) * gcd(a[i], a[j] - 1)的和.

两数互素,gcd(a[i], a[j]) * gcd(a[i], a[j] - 1)为0;
求任意一个以x为gcd的数对在数列中有k,则最多有k*k个数对的gcd为x,又已知两个数,如果他们都是 x 的倍数,那么他们的 gcd 一定也是 x 的倍数,即他们的gcd为x, 2x, …;
所以用f(x) 表示以 x 为 gcd 的数对个数。
f(x) = k^2 - f(2x) - f(3x) - f(4x) … f(tx) (tx <= 10000, k = Cnt[x])

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#define LL __int64
#define MAX 0x3f3f3f3f
#define MOD 10007
#define N (10000 + 5)

using namespace std;

int a[N], b[N]; 

int main()
{
    int n;

    while (~scanf("%d", &n))
    {
        memset(a, 0, sizeof(a));
        for (int i = 0; i < n; i++)
        {
            int t;
            scanf("%d", &t);

            for (int j = 1; j * j <= t; j++)
            {
                if (t % j == 0)
                {
                    a[j]++;

                    if (j * j != t)
                    {
                        a[t/j]++;
                    }
                }
            }
        }

        int ans = 0;

        for (int i = 10000; i >= 1; i--)
        {
            b[i] = a[i] * a[i] % MOD;

            for (int j = i * 2; j <= 10000; j += i)
            {
                b[i] = (b[i] - b[j] + MOD) % MOD;
            }

            ans = (ans + (i * (i - 1) % MOD * b[i] % MOD)) % MOD;
        }

        printf("%d\n", ans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值