快速傅立叶之二
快速傅立叶之二
https://ac.nowcoder.com/acm/problem/212551
分析
联系一下基础卷积。 ,虽然这个不是最基本的卷积形式,但是我们可以通过,令 ,那么原式变为 而 是一个常数,所以我们成功的构造了卷积形式。做一次 就好了。
代码
#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]); }
数学 文章被收录于专栏
关于多项式