题意:
数据范围:n<=2e5,a(i)<=1e6
解法:
显 然 只 需 要 计 算 出 每 种 g c d 的 所 有 子 序 列 的 长 度 和 . 令 d [ i ] 表 示 g c d 为 i 的 长 度 和 , 那 么 a n s = ∑ i ∗ d [ i ] 考 虑 通 过 容 斥 计 算 d [ i ] : d [ i ] = g c d 为 i 的 倍 数 的 长 度 和 − d [ i ∗ 2 ] − d [ i ∗ 3 ] . . . . . . 剩 下 的 问 题 为 g c d 为 i 的 倍 数 的 长 度 和 如 何 计 算 : 设 有 c n t 个 i 的 倍 数 , 那 么 长 度 和 为 : C ( c n t , 1 ) ∗ 1 + C ( c n t , 2 ) ∗ 2 + . . . + C ( c n t , c n t ) ∗ c n t , 即 ∑ i = 1 c n t C ( c n t , i ) ∗ i . 试 着 化 简 一 下 : ∑ i = 1 c n t C ( c n t , i ) ∗ i = ∑ i = 1 c n t c n t ! i ! ∗ ( c n t − i ) ! ∗ i = ∑ i = 1 c n t c n t ! ( i − 1 ) ! ∗ ( c n t − i ) ! = ∑ i = 1 c n t ( c n t − 1 ) ! ( i − 1 ) ! ∗ ( c n t − i ) ! ∗ c n t = ∑ i = 1 c n t C ( c n t − 1 , i − 1 ) ∗ c n t = c n t ∗ ∑ i = 1 c n t C ( c n t − 1 , i − 1 ) = c n t ∗ ∑ i = 0 c n t − 1 C ( c n t − 1 , i ) = c n t ∗ 2 c n t − 1 显然只需要计算出每种gcd的所有子序列的长度和.\\ 令d[i]表示gcd为i的长度和,那么ans=\sum i*d[i]\\ 考虑通过容斥计算d[i]:\\ d[i]=gcd为i的倍数的长度和-d[i*2]-d[i*3]......\\ 剩下的问题为gcd为i的倍数的长度和如何计算:\\ 设有cnt个i的倍数,那么长度和为:\\ C(cnt,1)*1+C(cnt,2)*2+...+C(cnt,cnt)*cnt,\\ 即\sum_{i=1}^{cnt}C(cnt,i)*i.\\ 试着化简一下:\\ \sum_{i=1}^{cnt}C(cnt,i)*i\\ =\sum_{i=1}^{cnt} \frac{cnt!}{i!*(cnt-i)!}*i\\ =\sum_{i=1}^{cnt} \frac{cnt!}{(i-1)!*(cnt-i)!}\\ =\sum_{i=1}^{cnt} \frac{(cnt-1)!}{(i-1)!*(cnt-i)!}*cnt\\ =\sum_{i=1}^{cnt}C(cnt-1,i-1)*cnt\\ =cnt*\sum_{i=1}^{cnt}C(cnt-1,i-1)\\ =cnt*\sum_{i=0}^{cnt-1}C(cnt-1,i)\\ =cnt*2^{cnt-1} 显然只需要计算出每种gcd的所有子序列的长度和.令d[i]表示gcd为i的长度和,那么ans=∑i∗d[i]考虑通过容斥计算d[i]:d[i]=gcd为i的倍数的长度和−d[i∗2]−d[i∗3]......剩下的问题为gcd为i的倍数的长度和如何计算:设有cnt个i的倍数,那么长度和为:C(cnt,1)∗1+C(cnt,2)∗2+...+C(cnt,cnt)∗cnt,即i=1∑cntC(cnt,i)∗i.试着化简一下:i=1∑cntC(cnt,i)∗i=i=1∑cnti!∗(cnt−i)!cnt!∗i=i=1∑cnt(i−1)!∗(cnt−i)!cnt!=i=1∑cnt(i−1)!∗(cnt−i)!(cnt−1)!∗cnt=i=1∑cntC(cnt−1,i−1)∗cnt=cnt∗i=1∑cntC(cnt−1,i−1)=cnt∗i=0∑cnt−1C(cnt−1,i)=cnt∗2cnt−1
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=1e6+5;
const int mod=1e9+7;
int cnt[maxm];
int p2[maxm];
int d[maxm];
int a[maxm];
int n;
void solve(){
p2[0]=1;
for(int i=1;i<maxm;i++)p2[i]=p2[i-1]*2%mod;
cin>>n;
for(int i=1;i<=n;i++){
int x;cin>>x;
a[x]++;
}
for(int i=1;i<maxm;i++){//cnt[i]=i的倍数.
for(int j=i;j<maxm;j+=i){
cnt[i]+=a[j];
}
}
for(int i=maxm-1;i>=2;i--){
if(!cnt[i])continue;
d[i]=cnt[i]*p2[cnt[i]-1]%mod;
for(int j=i+i;j<maxm;j+=i){
d[i]=(d[i]-d[j])%mod;
}
}
int ans=0;
for(int i=2;i<maxm;i++){
ans=(ans+i*d[i]%mod)%mod;
}
ans=(ans%mod+mod)%mod;
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
solve();
return 0;
}