ARC102E Stop. Otherwise... 题解
这是一个没有必要的复杂做法,但我考场上第一时间想到的就是这个做法。
分析
首先观察样例。发现答案有对称性,所以我们只需要求出
推式子
设
上面的式子中,
发现两个含有
在用过范德蒙德卷积后,这个式子求和的复杂度为
代码
#include <bits/stdc++.h>
using namespace std;
const int N=2e3+5;
const int MOD=998244353;
void exgcd(int a,int &x,int b,int &y){
if(!b){
x=1;
y=0;
}else{
exgcd(b,y,a%b,x);
y-=a/b*x;
}
}
int Inv(int x){
int res,y;
exgcd(x,res,MOD,y);
return (res%MOD+MOD)%MOD;
}
int Add(int a,int b){
return a+b>=MOD?a+b-MOD:a+b;
}
int Sub(int a,int b){
return a-b<0?a-b+MOD:a-b;
}
int Mul(int a,int b){
return 1ll*a*b%MOD;
}
int Div(int a,int b){
return 1ll*a*Inv(b)%MOD;
}
int qpow(int a,int b){
int res=1;
while(b){
if(b&1){
res=Mul(res,a);
}
a=Mul(a,a);
b>>=1;
}
return res;
}
int n,k,f[2*N],fac[2*N],infac[2*N];
int C(int n,int m){
return n>=m?Mul(fac[n],Mul(infac[m],infac[n-m])):0;
}
int main(){
scanf("%d%d",&k,&n);
fac[0]=1;
for(int i=1;i<=n+k;i++){
fac[i]=Mul(fac[i-1],i);
}
infac[n+k]=Inv(fac[n+k]);
for(int i=n+k-1;i>=0;i--){
infac[i]=Mul(infac[i+1],i+1);
}
for(int i=1;2*i<=k+1;i++){
for(int j=0;j<=min(i,n);j++){
f[2*i]=Add(f[2*i],Mul(Mul(qpow(2,j),C(i,j)),C(n+k-2*i-1,n-j)));
}
}
for(int i=1;2*i<=k;i++){
f[2*i+1]=f[2*k+2-2*i]=f[2*k+2-2*i-1]=f[2*i];
}
for(int i=2;i<=2*k;i++){
printf("%d\n",f[i]);
}
return 0;
}