CF839D Winter is here

CF839D Winter is here

问题相当于从\(a\)中选\(k\)个数求 \(k*gcd(a_{i_1},a_{i_2},...,a_{i_k})\) 的和。

考虑\(dp_i\)表示\(gcd=i\)的贡献。

在不考虑算重的情况下,方案数为:

\(dp_i=\sum\limits_{j=1}^{num_{i}}j{\binom{num_{i}}{j}}=n*2^{num_i-1}\)

其中\(num_i\)表示\(a\)中为\(i\)的倍数的数的个数。

考虑去重,设容斥系数为\(f_i\)

初始\(f_i=i\)

因为一个数只会在他的因数被算重所以

\(f_i=f_i-\sum\limits_{j|i}f_j\)

那么最后的答案为

\(ans=\sum\limits_{i=1}^{max}dp_i*f_i\)

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
long long pre[1000005],ans,tmp[1000005];
int a[200005],b[1000005],num;
int cnt,n,m;
void init(){
	pre[0]=1;
	for(int i=1;i<=1000000;i++){
		pre[i]=pre[i-1]*2ll%mod;
	}
}
int main(){
	init();
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		b[a[i]]++;
	}
	for(int i=2;i<=1000000;i++){
		tmp[i]=i;
	}
	for(int i=2;i<=1000000;i++){
		for(int j=i*2;j<=1000000;j+=i){
			tmp[j]-=tmp[i];
		}
	}
	for(int i=2;i<=1000000;i++){
		num=0;
		for(int j=i;j<=1000000;j+=i){
			num+=b[j];
		}
		ans+=pre[num-1]*1ll*num%mod*tmp[i]%mod;
		ans=(ans+mod)%mod;
	}
	printf("%lld",ans);
}
posted @ 2021-11-26 21:08  zhi_kong  阅读(61)  评论(0)    收藏  举报