首页 > 代码库 > [CF] 839.D
[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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。