[CF] 839.D
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF] 839.D相关的知识,希望对你有一定的参考价值。
题意;给出长度为n的序列a 若子序列b[1]..b[k]其gcd(b1..bk)>1 则贡献k*gcd(b1..bk)
n<=1e5,a[i]<=1e6,求所有贡献之和.
枚举gcd为i时对答案的贡献,贡献为i*(1*k[1]+2*k[2]+..m*k[m]) k[j]为子序列为gcd为i,长度为j的个数,令括号部分为f[i]
当i的倍数有n个时,贡献(包含重复)为i*(k=1~n)C(n,k)*k = n*2^(n-1)
扣掉重复部分f[pi](p>1)即可.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e6+20; const int mod=1e9+7; ll f[N],cnt[N],pw2[N]; int n,a[N]; int main() { pw2[0]=1; for(int i=1;i<N;i++) pw2[i]=(pw2[i-1]*2ll)%mod; while(cin>>n) { memset(f,0,sizeof(f)); int mx=0; ll ans=0; for(int i=1;i<=n;i++) scanf("%d",&a[i]),cnt[a[i]]++,mx=max(mx,a[i]); for(int i=mx;i>=2;i--) { ll tot=0; for(int j=i;j<=mx;j+=i) tot+=cnt[j]; ll res=(tot*pw2[tot-1])%mod;//(i=1~n)C(n,i)*i = n*2^(n-1) for(int j=i+i;j<=mx;j+=i) res=(res-f[j]+mod)%mod; f[i]=res; ans=(ans+(ll)i*f[i]%mod)%mod; } cout<<ans<<endl; } return 0; }
以上是关于[CF] 839.D的主要内容,如果未能解决你的问题,请参考以下文章