洛谷 P4721 【模板】分治 FFT 解题报告

P4721 【模板】分治 FFT

题目背景

也可用多项式求逆解决。

题目描述

给定长度为 \(n−1\) 的数组 \(g[1],g[2],\dots,g[n-1]\),求 \(f[0],f[1],\dots,f[n-1]\),其中\(f[i]=\sum_{j=1}^if[i-j]g[j]\)

边界为 \(f[0]=1\) 。答案模 \(998244353\)

输入输出格式

输入格式:

第一行一个正整数 \(n\)

第二行共 \(n−1\) 个非负整数 \(g[1],g[2],\dots,g[n-1]\),用空格隔开。

输出格式:

一行共 \(n\) 个非负整数,表示 \(f[0],f[1],\dots,f[n-1]\)\(998244353\) 的值。

说明

\(2\leq n\leq 10^5\)

\(0\leq g[i]<998244353\)


其实就是用了一下\(\text{CDQ}\)分治而已,听说比多项式求逆的应用范围要广一些 ,虽然复杂度是\(O(n\log^2n)\)的。

实现细节

  • 和斜率优化一样先左然后做然后去右边
  • 每次做NTT时注意不要从右半边的\(f\)取值,那边不是0...

Code:

#include <cstdio>
#include <algorithm>
#define ll long long
const int N=(1<<18)+10;
const ll mod=998244353,G=3,Gi=332748118;
#define mul(a,b) a*b%mod
ll qp(ll d,ll k){ll f=1;while(k){if(k&1) f=mul(f,d);d=mul(d,d);k>>=1;}return f;}
ll f[N],g[N],a[N],b[N];
int n,len,L,turn[N];
void NTT(ll *a,int typ)
{
    for(int i=0;i<len;i++)
        if(i<turn[i])
            std::swap(a[i],a[turn[i]]);
    for(int le=1;le<len;le<<=1)
    {
        ll wn=qp(typ?G:Gi,(mod-1)/(le<<1));
        for(int p=0;p<len;p+=le<<1)
        {
            ll w=1;
            for(int i=p;i<p+le;i++,w=w*wn%mod)
            {
                ll tmpx=a[i],tmpy=w*a[i+le]%mod;
                a[i]=(tmpx+tmpy)%mod;
                a[i+le]=(tmpx-tmpy)%mod;
            }
        }
    }
}
void CDQfft(int l,int r)
{
    if(l==r) {(f[l]+=g[l])%=mod;return;}
    int mid=l+r>>1;
    CDQfft(l,mid);
    int m=r+1-l;
    len=1,L=-1;
    while(len<=m<<1) len<<=1,++L;
    for(int i=0;i<len;i++) a[i]=b[i]=0,turn[i]=turn[i>>1]>>1|(i&1)<<L;
    for(int i=l;i<=mid;i++) a[i+1-l]=f[i];
    for(int i=1;i<=r+1-l;i++) b[i]=g[i];
    NTT(a,1),NTT(b,1);
    for(int i=0;i<len;i++) a[i]=mul(a[i],b[i]);
    NTT(a,0);
    ll inv=qp(len,mod-2);
    for(int i=mid+1;i<=r;i++) (f[i]+=mul(a[i+1-l],inv))%=mod;
    CDQfft(mid+1,r);
}
int main()
{
    scanf("%d",&n);--n;
    for(int i=1;i<=n;i++) scanf("%lld",g+i);
    f[0]=1;
    CDQfft(1,n);
    for(int i=0;i<=n;i++) printf("%lld ",(f[i]+mod)%mod);
    return 0;
}

2018.12.6

posted @ 2018-12-06 20:38  露迭月  阅读(188)  评论(0编辑  收藏  举报