GCD Expectation
Time Limit: 4000ms
Memory Limit: 262144KB
This problem will be judged on ZJU. Original ID: 386864-bit integer IO format: %lld Java class name: Main
Edward has a set of n integers {a1, a2,...,an}. He randomly picks a nonempty subset {x1, x2,…,xm} (each nonempty subset has equal probability to be picked), and would like to know the expectation of [gcd(x1, x2,…,xm)]k.
Note that gcd(x1, x2,…,xm) is the greatest common divisor of {x1, x2,…,xm}.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains two integers n, k (1 ≤ n, k ≤ 106). The second line contains n integers a1, a2,…,an (1 ≤ ai ≤ 106).
The sum of values max{ai} for all the test cases does not exceed 2000000.
Output
For each case, if the expectation is E, output a single integer denotes E · (2n - 1) modulo 998244353.
Sample Input
1 5 1 1 2 3 4 5
Sample Output
42
Source
Author
LIN, Xi
解题:我们采取的是枚举gcd的策略
真子集的个数为$2^{cnt}-1$个数
但是我们发现,算我们枚举的gcd的时候,真正的gcd确实我们枚举的gcd的倍数
所以要去重,利用容斥原理
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int mod = 998244353; 5 const int maxn = 1000010; 6 LL dp[maxn]; 7 int sum[maxn]; 8 LL quickPow(LL base,int index){ 9 LL ret = 1; 10 while(index){ 11 if(index&1) ret = ret*base%mod; 12 index >>= 1; 13 base = base*base%mod; 14 } 15 return ret; 16 } 17 int main(){ 18 int kase,n,k,mxv,tmp; 19 scanf("%d",&kase); 20 while(kase--){ 21 scanf("%d%d",&n,&k); 22 memset(sum,0,sizeof sum); 23 for(int i = mxv = 0; i < n; ++i){ 24 scanf("%d",&tmp); 25 sum[tmp]++; 26 mxv = max(mxv,tmp); 27 } 28 LL ret = 0; 29 for(int i = mxv; i > 0; --i){ 30 int cnt = dp[i] = 0; 31 for(int j = i; j <= mxv; j += i){ 32 dp[i] = (dp[i] - dp[j] + mod)%mod; 33 cnt += sum[j]; 34 } 35 dp[i] = (dp[i] + quickPow(2,cnt) - 1)%mod; 36 ret = (ret + dp[i]*quickPow(i,k))%mod; 37 } 38 printf("%lld ",ret); 39 } 40 return 0; 41 }