【容斥原理】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;
}
上一篇:用TableView写带特效的cell


下一篇:设置网站expires和max-age属性