参考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;
}