【bzoj4146】[AMPPZ2014]Divisors 数论

原文地址:http://www.cnblogs.com/GXZlegend/p/6801411.html


题目描述

给定一个序列a[1],a[2],...,a[n]。求满足i!=j且a[i]|a[j]的二元组(i,j)的个数。

输入

第一行包含一个正整数n(1<=n<=2000000),表示序列长度。
第二行包含n个正整数,依次表示a[1],a[2],...,a[n](1<=a[i]<=2000000)。

输出

一个整数,即满足条件的二元组的个数。

样例输入

5
2 4 5 2 6

样例输出

6


题解

数论

根据微积分什么的能得出n/1+n/2+...+n/n<n(ln n+1)

然后枚举1到maxa的每个数。

由于两个相同的数符合条件,则当有n个相同的数时二元组个数为n(n-1)。

再依次向上查找该数的倍数,二元组个数为n1*n2。

然后加起来就好了。

#include <cstdio>
#include <algorithm>
using namespace std;
long long v[2000010];
int main()
{
	int n , m = 0 , i , j , x;
	long long ans = 0;
	scanf("%d" , &n);
	for(i = 1 ; i <= n ; i ++ )
		scanf("%d" , &x) , v[x] ++ , m = max(m , x);
	for(i = 1 ; i <= m ; i ++ )
	{
		ans += v[i] * (v[i] - 1);
		for(j = 2 * i ; j <= m ; j += i) ans += v[i] * v[j];
	}
	printf("%lld\n" , ans);
	return 0;
}

 

posted @ 2017-05-03 13:08  GXZlegend  阅读(282)  评论(0编辑  收藏  举报