[HDOJ 5212] [BestCoder Round#39] Code 【0.0】

题目链接:HDOJ - 5212

 

题目分析

首先的思路是,考虑每个数对最终答案的贡献。

那么我们就要求出:对于每个数,以它为 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 <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#include <queue>

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef double LF;

inline int gmin(int a, int b) {return a < b ? a : b;}
inline int gmax(int a, int b) {return a > b ? a : b;}

inline LF gmin(LF a, LF b) {return a < b ? a : b;}
inline LF gmax(LF a, LF b) {return a > b ? a : b;}

const LF Eps = 1e-8;

inline LF Sqr(LF x) {return x * x;}

inline int Sgn(LF x)
{
    if (x < -Eps) return -1;
    if (x > Eps) return 1;
    return 0;    
}

const int MaxN = 10000 + 5, Mod = 10007;

int n, Ans, Num, Temp, SqrtX;
int Cnt[MaxN], f[MaxN], Pos[MaxN];

int main()
{
    while (scanf("%d", &n) != EOF)
    {
    	for (int i = 1; i <= 10000; ++i) Cnt[i] = 0;
       	for (int i = 1; i <= n; ++i) 
       	{
    		scanf("%d", &Num);
    		SqrtX = (int)sqrt((LF)Num);
    		for (int j = 1; j <= SqrtX; ++j)
    		{
    			if (Num % j != 0) continue;
				++Cnt[j];
    			if (Num / j != j) ++Cnt[Num / j];
    		}
       	}
       	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;
       		Temp = i * (i - 1) % Mod;
       		Ans = (Ans + f[i] * Temp % Mod) % Mod;
       	}
        printf("%d\n", Ans);
    }
    return 0;
}

  

posted @ 2015-04-26 22:55  JoeFan  阅读(426)  评论(0编辑  收藏  举报