參考http://www.kuangbin.net/archives/15th_zju
I-GCD Expectation
http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5471
///參考了kuangbin大神的
#include <iostream>
#include <cstdio>
#include <cstring>
#define max(a,b) (a)>(b)?(a):(b)
#define N 1000002
#define mod 998244353
using namespace std;
int b[N];
long long dp[N];
long long pow_m(long long a,long long n){
long long ret = 1;
long long tmp = a;
while(n){
if(n&1)ret = ret*tmp%mod;
tmp = tmp*tmp%mod;
n >>= 1;
}
return ret;
}
int main()
{
int t;
scanf("%d",&t);
int n,k;
while(t--){
scanf("%d%d",&n,&k);
memset(b,0,sizeof(b));
int temp,max0=-1;///找出最大數
for(int i=0;i<n;i++){
scanf("%d",&temp);
b[temp]++;///集合中有重複的數,建個表方便查
max0=max(max0,temp);
}
long long sum=0;
int cnt;///計算i倍數的個數
for(int i=max0;i>=1;i--)
{
dp[i]=0;
cnt=0;
for(int j=i;j<=max0;j=j+i){///順便求了倍數
cnt+=b[j];///記了有多少個
if(j>i)dp[i]=(dp[i]-dp[j]+mod)%mod;///計算gcd爲i的子集個數,需要減去i的倍數纔是他單獨的
}///求和
///那麼如果i的倍數有x個, 那麼gcd爲 i的倍數的子集個數就是 2^x - 1
dp[i]=(dp[i]+pow_m(2,cnt)-1+mod)%mod;
sum+=dp[i]*pow_m(i,k)%mod;///按要求求和
sum%=mod;
}
cout<<sum<<endl;
}
return 0;
}