【容斥原理】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; }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/