Time Limit: 4 Seconds Memory Limit: 262144 KB
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}.
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.
For each case, if the expectation is E, output a single integer denotes E · (2n - 1) modulo 998244353.
1
5 1
1 2 3 4 5
42
#include <iostream> #include <stdio.h> #include <cmath> #include <algorithm> #include <string.h> #define LL long long #define scan(a) scanf("%d",&a) #define REP(i,a,b) for(int i=a;i<b;++i) #define mset(a,b) memset(a,b,sizeof a) //#define maxn 1e6+10 using namespace std; const LL mod = 998244353; const int maxn = 1e6+10; LL F[maxn]; LL pow2[maxn]; int k; int miu[maxn]; int a[maxn]; bool check[maxn]; int prime[maxn]; void Moblus() { mset(check,0); miu[1]=1; int tot=0; for(int i=2;i<=maxn ;++i) { if(!check[i]) { prime[tot++]=i; miu[i]=-1; } REP(j,0,tot) { if(i*prime[j] >maxn) break; check[i*prime[j]]=true; if(i%prime[j] ==0) { miu[i*prime[j]] = 0; break; } else { miu[i*prime[j]] = -miu[i]; } } } } LL _pow(LL d,int k) { if(k==1) return d%mod; LL ret=_pow(d,k/2) ; ret *=ret; ret%=mod; if(k&1) ret=ret*d; return ret%mod; } int maxan=0; void preF(int n) { mset(F,0); maxan=0; REP(i,0,n) { F[a[i]]++; maxan=max(maxan,a[i]); } F[1]=n; REP(i,2,maxan+1) { for(int j=i+i;j<=maxan;j+=i) { F[i] += F[j]; F[i]%=mod; } } REP(i,1,maxan+1) { F[i]=pow2[F[i]]-1; if(F[i]<0) F[i]+=mod; } } LL solve() { LL ret=0; LL sum=0; REP(i,1,maxan+1) { sum=0; for(int j=i;j<=maxan;j+=i) { sum+= miu[j/i]*F[j]; sum%=mod; } if(i>1) sum=sum*_pow(i,k); sum%=mod; ret+=sum; if(ret>=mod) ret-=mod; } return ret; } int main() { Moblus(); pow2[0]=1; REP(i,1,maxn) pow2[i]=pow2[i-1]*2%mod; int t,n; cin>>t; while(t--) { cin>>n>>k; REP(i,0,n) scan(a[i]); preF(n); LL ans=solve(); cout<<ans<<endl; } }