洛谷月赛的题目,不会做,只会打20分的baoli,看了题解也没弄明白怎么线性求多项式的,lypAC啦后,抄了他的代码,才明白。
还是不会用markdown写公式,只好手写啦。参考代码:我抄的啦!
//copy form lyp
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MaAXN = 1e7 + 1;
const int mod = 998244353;
bool isnp[MAXN];
int p[MAXN],pcnt=0;
int pre[MAXN];//记录其没有最后一个因子的的数。
int b[MAXN][9+1];//分解后因数的系数多项式的积,分解的因数前面的大于后面的。
void sieve(int n) {
isnp[0]=isnp[1]=1;
b[1][0]=1;
for(int i=2; i<=n; ++i) {
if(!isnp[i]) {
p[++pcnt]=i;
b[i][0]=1;
b[i][1]=1;
pre[i]=1;
}
for(int j=1; j<=pcnt; ++j) {
if((ll)i*p[j]>n) break;
int now = i*p[j];
isnp[now]=1;
if(i%p[j]) {// (1+a1)(1+a2)*...*(1+aj) //增加了 ai且aj=1;
pre[now] = i;
for(int k=0; k<=8; ++k) b[now][k]=b[i][k];
for(int k=0; k<8; ++k) b[now][k+1]+= b[i][k];
} else {//(1+a1)(1+a2)*...*(1+aj+1) //aj增加了1
pre[now] = pre[i];
for(int k=0; k<=8; ++k) b[now][k] = b[i][k];
for(int k=0; k<8; ++k) b[now][k+1]+=b[pre[i]][k];
break;
}
}
}
for(int i=1; i<=n; ++i)
for(int j=0; j<=8; ++j)
b[i][j]=(b[i][j]+b[i-1][j])%mod;
}
int pwd[9];
int main(void) {
sieve(1e7);
int T;
scanf("%d",&T);
while(T--) {
int n,d;
scanf("%d%d",&n,&d);
pwd[0]=1;
for(int i=1; i<=8; ++i)
pwd[i] = (ll)pwd[i-1]*d %mod;
int ans=0;
for(int i=0; i<=8; ++i)
ans=((ll)ans+(ll)b[n][i]*pwd[i]) %mod;
printf("%d\n",ans);
}
return 0;
}