HDU 5212 Code(容斥 或 莫比乌斯反演)

Code

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description

WLD likes playing with codes.One day he is writing a function.Howerver,his computer breaks down because the function is too powerful.He is very sad.Can you help him?

The function:

int calc

{

int res=0;

for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++)

{

res+=gcd(a[i],a[j])*(gcd(a[i],a[j])-1);

res%=10007;

}

return res;

}

Input

There are Multiple Cases.(At MOST 10)

For each case:

The first line contains an integer N(1≤N≤10000).

The next line contains N integers a1,a2,...,aN(1≤ai≤10000).

Output

For each case:

Print an integer,denoting what the function returns.

Sample Input

5
1 3 4 2 4

Sample Output

64

Hint

gcd(x,y) means the greatest common divisor of x and y.

原文:http://www.cnblogs.com/JoeFan/p/4458629.html

题意:给出n个数,求gcd(a[i], a[j]) * gcd(a[i], a[j] - 1)的和(1 <= i, j <= n)。

分析:首先,我们分析每个数对最终答案的影响。

那么我们就要求出:对于每个数,以它为 gcd 的数对有多少对。

显然,对于一个数 x ,以它为 gcd 的两个数一定都是 x 的倍数。如果 x 的倍数在数列中有 k 个,那么最多有 k^2 对数的 gcd 是 x 。

同样显然的是,对于两个数,如果他们都是 x 的倍数,那么他们的 gcd 一定也是 x 的倍数。

所以,我们求出 x 的倍数在数列中有 k 个,然后就有 k^2 对数满足两个数都是 x 的倍数,这 k^2 对数的 gcd,要么是 x ,要么是 2x, 3x, 4x...

并且,一个数是 x 的倍数的倍数,它就一定是 x 的倍数。所以以 x 的倍数为 gcd 的数对,一定都包含在这 k^2 对数中。

如果我们从大到小枚举 x ,这样计算 x 的贡献时,x 的多倍数就已经计算完了。我们用 f(x) 表示以 x 为 gcd 的数对个数。

那么 f(x) = k^2 - f(2x) - f(3x) - f(4x) ... f(tx)       (tx <= 10000, k = Cnt[x])

这样枚举每个 x ,然后枚举每个 x 的倍数,复杂度用调和级数计算,约为 O(n logn)。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

const int MaxN = 1e4 + 10;
const int Mod = 10007;

int cnt[MaxN], F[MaxN];

int main() {
    int n, a;
    while(~scanf("%d", &n)) {
        memset(cnt, 0, sizeof(cnt));
        for(int i = 0; i < n; i++) {
            scanf("%d", &a);
            for(int j = 1; j * j <= a; j++) {
                if(a % j == 0) {
                    cnt[j]++;
                    if(j * j != a)
                        cnt[a / j]++;
                }
            }
        }
        int ans = 0;
        for(int i = 10000; i >= 1; i--) {
            F[i] = cnt[i] * cnt[i] % Mod;
            for(int j = i * 2; j <= 10000; j += i)
                F[i] = (F[i] - F[j] + Mod) % Mod;
            int p = i * (i - 1) % Mod;
            ans = (ans + p * F[i] % Mod) % Mod;
        }
        printf("%d\n", ans);
    }
    return 0;
}
时间: 2024-09-30 11:29:48

HDU 5212 Code(容斥 或 莫比乌斯反演)的相关文章

HDU 1695 GCD(容斥 or 莫比乌斯反演)

这题可以用容斥做,然而效率并不高.. 于是学了下莫比乌斯反演(资料百度找) 求出mo数组后 设f(x)为gcd为x的种数 F(x)为gcd为x倍数的种数 那么显然F(x) = (b / x) * (d / x) 莫比乌斯反演之后,得到f(x) = sum(mo[i] * F(i)). 然后还要容斥减去对称重复的.对称重复的情况为min(b, d)小的中,求一遍除2,(因为存在x = y的情况只有(1,1)一种) 最后还要注意特判下k == 0的情况 代码: #include <cstdio>

POJ 3904 Sky Code (容斥+莫比乌斯反演)

Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1831   Accepted: 570 Description Stancu likes space travels but he is a poor software developer and will never be able to buy his own spacecraft. That is why he is preparing to ste

hdu 5212 反向容斥或者莫比

http://acm.hdu.edu.cn/showproblem.php?pid=5212 题意:忽略.. 题解:把题目转化为求每个gcd的贡献.(http://www.cnblogs.com/z1141000271/p/7419717.html 和这题类似 反向容斥)这里先用容斥写了,mobious的之后再说吧23333. 然后比较想说的是这个调和级数的复杂度 nlog(n) ac代码: #include <iostream> #include <cstdio> #includ

BZOJ 2440 完全平方数 (容斥+莫比乌斯反演+二分)

2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1673  Solved: 799 [Submit][Status][Discuss] Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨厌完全平方数.他觉得这些 数看起来很令人难受.由此,他也讨厌所有是完全平方数的正整数倍的数.然而 这丝毫不影响他对其他数的热爱. 这天是小X的生日,小 W 想送一个数给他作为生日礼物.当然他不能送一 个

BZOJ 2301 [HAOI2011]Problem b (容斥+莫比乌斯反演+分块优化 详解)

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 2096  Solved: 909 [Submit][Status][Discuss] Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数n,接下来n行每行五个整数,分别表示a.b.c.d.k Out

UESTC 618 无平方因子数 (容斥 + 莫比乌斯反演)

无平方因子数 Time Limit: 4000/2000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit  Status 无平方因子数即对于任意一个素数p,p2都不会整除那个数,如1 , 5=5 , 15=3×5都是无平方因子数,而20=22×5不是.现在给定一个n (1≤n<1012) ,求区间[1,n]中无平方因子数的个数. Input 第一行有个整数T,代表数据组数(T≤10) 接下来有T行,每行有个整数n

hdu 5514 Frogs(容斥)

Frogs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1315    Accepted Submission(s): 443 Problem Description There are m stones lying on a circle, and n frogs are jumping over them.The stones a

HDU 5213 分块 容斥

给出n个数,给出m个询问,询问 区间[l,r] [u,v],在两个区间内分别取一个数,两个的和为k的对数数量. $k<=2*N$,$n <= 30000$ 发现可以容斥简化一个询问.一个询问的答案为 $[l,v]+(r,u)-[l,u)-(r,v]$,那么我们离线询问,将一个询问分成四个,分块暴力就行了. 然后就是注意细节,不要发生越界,访问错位置之类比较蠢的问题了. /** @Date : 2017-09-24 19:54:55 * @FileName: HDU 5213 分块 容斥.cpp

hdu.5212.Code(莫比乌斯反演 &amp;&amp; 线性筛)

Code Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 300    Accepted Submission(s): 124 Problem Description WLD likes playing with codes.One day he is writing a function.Howerver,his computer b