- 把G反过来原式就变成
这样对于确定的i,贡献都会卷到第n+r项,直接NTT
Code
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define ll long long
using namespace std;
const int mod=998244353;
const int N = 1e6;
char s[N],t[N];
int n,q,m,x,y,l,r[N],c[N],a[N],b[N],fact[N],ifact[N],ans[N];
int power(int a,int b){int ans=1;for(;b;b>>=1,a=1LL*a*a%mod)if(b&1)ans=1LL*ans*a%mod;return ans;}
void ntt(int *a, int f) {
for(int i = 0; i < n; i++) if(r[i] > i) swap(a[i], a[r[i]]);
for(int i = 1; i <n; i <<= 1) {
int wn=power(3,(mod-1)/(i*2));
if(f==-1)wn=power(wn,mod-2);
for(int j = 0; j < n; j += (i<<1)) {
int w = 1;
for(int k = 0; k < i; k++, w =1LL*w* wn%mod) {
int x = a[j+k], y = 1LL*w*a[j+k+i]%mod;
a[j+k] = x+y, a[j+k+i] = x-y;
a[j+k]=(a[j+k]%mod+mod)%mod;
a[j+k+i]=(a[j+k+i]%mod+mod)%mod;
}
}
}
if(f==-1){
int rev=power(n,mod-2);
rep(i,0,n-1) a[i]=((ll)a[i]*rev)%mod;
}
}
int main() {
scanf("%d%d", &m,&q);
fact[0]=1;rep(i,1,m)fact[i]=1LL*fact[i-1]*i%mod;
ifact[m]=power(fact[m],mod-2);
for(int i=m;i;i--)ifact[i-1]=1ll*ifact[i]*i%mod;
rep(i,2,m)a[i]=1ll*((i-1)/2)*fact[i-2]%mod;
rep(i,0,m)b[i]=ifact[m-i];
for(n = 1, m <<= 1; n <=m; n <<= 1) l++;
for(int i=0;i<n;i++)r[i]=r[i>>1]>>1|(i&1)<<(l-1);
ntt(a, 1), ntt(b, 1);
for(int i = 0; i < n; i++) a[i]=1LL*a[i]* b[i]%mod;
ntt(a, -1);
m>>=1;
for(int i=2;i<=m;i++)ans[i]=1ll*fact[m-i]*a[m+i]%mod;
while(q--){
scanf("%d%d",&x,&y);
printf("%d\n",ans[y]);
}
return 0;
}