題目描述
有n 顆珠子,珠子的編號依次爲1 到n。第i 顆珠子的美麗值爲vi,這是一個在1 到m 之間的正整數。
查爾明將會從中等概率隨機抽取1 到n 顆珠子,那麼此時他的高興度爲所有抽到的珠子的美麗值的最大公約數。查爾明想知道,他的期望高興度是多少,你能幫幫他嗎?因爲查爾明不喜歡實數和大數,所以你只需要輸出結果×(2^n − 1) 的值對998244353 取模的結果即可。
輸入
n, m
v1, v2, ……,vn
輸出
答案
樣例輸入
3 4
2 4 3
樣例輸出
14
提示
對於30% 的數據,n ≤ 20,m ≤ 100000。
對於另外30% 的數據,n ≤ 100000,m ≤ 20。
對於100% 的數據,n ≤ 100000,m ≤ 100000。
來源
Claris
分析:
先求出1~m中,每個數出現的次數,記爲a[]。
令f[i]表示選出的數所得的gcd是i的倍數的方案數,t爲在給出的n個數中i的倍數出現的次數
則:f[i] =
那麼根據容斥原理,令g[i]表示選出的數所得的gcd是i的方案數
則:
ans=
不要忘記%Mod哦,前面的推導都沒有寫%Mod
#include<cstdio>
#define MAXN 100000
#define Mod 998244353
typedef long long LL;
LL n,m,a[MAXN+10],f[MAXN+10],g[MAXN+10],P[MAXN+10],ans;
int main()
{
LL x;
scanf("%I64d%I64d",&n,&m);
for(LL i=1;i<=n;i++){
scanf("%I64d",&x);
a[x]++;
}
P[0]=1;
for(LL i=1;i<=n;i++)
P[i]=P[i-1]*2%Mod;
for(LL i=1;i<=m;i++){
LL cnt=0;
for(LL j=i;j<=m;j+=i)
cnt+=a[j];
f[i]=(P[cnt]-1)%Mod;
}
for(LL i=m;i>=1;i--){
LL sum=0;
for(LL j=i+i;j<=m;j+=i)
sum=(sum+g[j])%Mod;
g[i]=(f[i]-sum+Mod)%Mod;
}
for(LL i=1;i<=m;i++)
ans=(ans+i*g[i]%Mod)%Mod;
printf("%lld\n",ans);
return 0;
}