快速傅立叶之二

快速傅立叶之二

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]);
}
数学 文章被收录于专栏

关于多项式

全部评论

相关推荐

有工作后先养猫:太好了,是超时空战警,我们有救了😋
点赞 评论 收藏
分享
评论
3
4
分享
牛客网
牛客企业服务