分析
联系一下基础卷积。 ,虽然这个不是最基本的卷积形式,但是我们可以通过,令
,那么原式变为
而
是一个常数,所以我们成功的构造了卷积形式。做一次
就好了。
代码
#include<bits/stdc++.h>
using namespace std;
int read() {
int x = 0,f = 0;char ch = getchar();
while(!isdigit(ch)) {if(ch=='-')f=1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return f?-x:x;
}
const int N = 6e5 + 100,P = 998244353;
int limit = 1,L,r[N];
int qpow(int x,int b) {
int a = 1;
for(;b;b>>=1,x=1LL*x*x%P) {
if(b&1) a = 1LL * a * x % P;
}
return a;
}
void ntt(int *a,int type) {
for(int i = 0;i < limit;i++) if(i < r[i]) swap(a[i],a[r[i]]);
for(int mid = 1;mid < limit;mid <<= 1) {
int wn = qpow(3,(P-1)/(mid<<1));
for(int i = 0;i < limit;i += (mid<<1)) {
int w = 1;
for(int j = 0;j < mid;j++,w=1LL*w*wn%P) {
int x = a[i + j], y = 1LL * w * a[i + j + mid] % P;
a[i + j] = (x + y) % P;
a[i + j + mid] = (x - y + P) % P;
}
}
}
if(type == -1) {
reverse(a+1,a+limit);int inv = qpow(limit,P-2);
for(int i = 0;i < limit;i++) a[i] = 1LL * a[i] * inv % P;
}
}
int a[N],b[N],c[N],n;
int main() {
n = read();
for(int i = 1;i <= n;i++) a[i] = read(),b[i] = read(),c[2 * n - i] = a[i];
while(limit <= n * 3) limit <<= 1,L++;
for(int i = 0;i < limit;i++) r[i] = (r[i>>1]>>1)|((i&1)<<L-1);
ntt(c,1);ntt(b,1);
for(int i = 0;i < limit;i++) c[i] = 1LL * c[i] * b[i] % P;
ntt(c,-1);
for(int i = n + n;i >= n + 1;i--) printf("%d\n", c[i]);
}
京公网安备 11010502036488号