【容斥原理】Codeforces Round #428 (Div. 2) D. Winter is here

给你一个序列,让你对于所有gcd不为1的子序列,计算它们的gcd*其元素个数之和。

设sum(i)为i的倍数的数的个数,可以通过容斥算出来。

具体看这个吧:http://blog.csdn.net/jaihk662/article/details/77161436。

注意1*C(n,1)+2*C(n,2)+...+n*C(n,n)=n*2^(n-1)。

#include<cstdio>
using namespace std;
typedef long long ll;
#define MOD 1000000007ll
int n;
int a[200005],cnt[1000005];
ll sum[1000005],ans,pw[1000005];
int main(){
	pw[0]=1;
	for(int i=1;i<=1000000;++i){
		pw[i]=(pw[i-1]*2ll)%MOD;
	}
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		++cnt[a[i]];
	}
	for(int i=1000000;i>=2;--i){
		int all=cnt[i];
		for(int j=i*2;j<=1000000;j+=i){
			sum[i]=(sum[i]+MOD-sum[j])%MOD;
			all+=cnt[j];
		}
		sum[i]=(sum[i]+((ll)all*pw[all-1])%MOD)%MOD;
		ans=(ans+((ll)i*sum[i])%MOD)%MOD;
	}
	printf("%I64d\n",ans);
	return 0;
}
posted @ 2017-08-16 23:13  AutSky_JadeK  阅读(134)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト