瞎扯

虽然说是FFT但是还是写了一发NTT(笑)

然后忘了IDFT之后要除个n懵逼了好久

以及递归的时候忘了边界无限RE

思路

朴素算法

分治FFT

考虑到题目要求求这样的一个式子

\[F_x=\Sigma_{i=1}^{x}F_{x-i}G_{i}
\]

我们可以按定义暴力,然后再松式卡常(不是)

我们可以发现它长得像一个卷积一样,但是因为后面的f值会依赖与前面的f值,所以没法一遍FFT直接求出结果,而对每个f都跑一遍FFT太慢了,我们使用分治优化这个过程就很优秀了,复杂度是\(O(n\log^2 n)\)

分治优化

我们能够想到cdq分治的思想,在统计一个区间时,确保对这个区间有影响的操作产生的贡献已经全被统计,就是先统计[l,mid]区间对[mid+1,r]区间的贡献

然后发现对于每个\(f_x\),它对后面的\(f_i\)产生的贡献是\(\Sigma_{j=l}^{mid} f_{i}g_{i-j}\)

然后分治就好

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std; const int MOD = 998244353,G=3,invG=332748118;
int a[200000],b[200000],f[200000],g[200000],n;
int pow(int a,int b){
int ans=1;
while(b){
if(b&1)
ans=(1LL*ans*a)%MOD;
a=(1LL*a*a)%MOD;
b>>=1;
}
return ans;
}
void FFT(int *a,int opt,int n){
int lim=0;
while((1<<lim)<n)
lim++;
for(int i=0;i<n;i++){
int t=0;
for(int j=0;j<lim;j++)
if((i>>j)&1)
t|=(1<<(lim-j-1));
if(i<t)
swap(a[i],a[t]);
}
for(int i=2;i<=n;i<<=1){
int len=i/2;
int tmp=pow((opt)?G:invG,(MOD-1)/i);
for(int j=0;j<n;j+=i){
int arr=1;
for(int k=j;k<len+j;k++){
int t=arr*a[k+len];
a[k+len]=((a[k]-t)%MOD+MOD)%MOD;
a[k]=(a[k]+t)%MOD;
arr=(arr*tmp)%MOD;
}
}
}
if(opt==0){
int invt=pow(n,MOD-2);
for(int i=0;i<n;i++)
a[i]=a[i]*invt%MOD;
}
}
void solve(int l,int r){
if(r-l==1)
return;
int t=pow(r-l,MOD-2);
int mid=(l+r)>>1;
solve(l,mid);
memset(a+(r-l)/2,0,sizeof(int)*(r-l)/2);
memcpy(a,f+l,sizeof(int)*(r-l)/2);
memcpy(b,g,sizeof(int)*(r-l));
FFT(a,1,r-l);
FFT(b,1,r-l);
for(int i=0;i<r-l;i++)
a[i]=(a[i]*b[i])%MOD;
FFT(a,0,r-l);
for(int i=(r-l)/2;i<r-l;i++)
f[l+i]=(f[l+i]+a[i])%MOD;
solve(mid,r);
}
signed main(){
int mid;
scanf("%lld",&n);
mid=n;
for(int i=1;i<=n-1;i++)
scanf("%lld",&g[i]);
int t=1;
while(t<n)
t<<=1;
n=t;
f[0]=1;
solve(0,n);
for(int i=0;i<mid;i++)
printf("%lld ",f[i]);
return 0;
}

P4721【模板】分治 FFT的更多相关文章

  1. 洛谷 P4721 [模板]分治FFT —— 分治FFT / 多项式求逆

    题目:https://www.luogu.org/problemnew/show/P4721 分治做法,考虑左边对右边的贡献即可: 注意最大用到的 a 的项也不过是 a[r-l] ,所以 NTT 可以 ...

  2. 洛谷.4721.[模板]分治FFT(NTT)

    题目链接 换一下形式:\[f_i=\sum_{j=0}^{i-1}f_jg_{i-j}\] 然后就是分治FFT模板了\[f_{i,i\in[mid+1,r]}=\sum_{j=l}^{mid}f_jg ...

  3. 解题:洛谷4721 [模板]分治FFT

    题面 这是CDQ入门题,不要被题目名骗了,这核心根本不在不在FFT上啊=.= 因为后面的项的计算依赖于前面的项,不能直接FFT.所以用CDQ的思想,算出前面然后考虑给后面的贡献 #include< ...

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

    P4721 [模板]分治 FFT 题目背景 也可用多项式求逆解决. 题目描述 给定长度为 \(n−1\) 的数组 \(g[1],g[2],\dots,g[n-1]\),求 \(f[0],f[1],\d ...

  5. [洛谷P4721]【模板】分治 FFT

    题目大意:给定长度为$n-1$的数组$g_{[1,n)}$,求$f_{[0,n)}$,要求: $$f_i=\sum_{j=1}^if_{i-j}g_j\\f_0=1$$ 题解:直接求复杂度是$O(n^ ...

  6. 洛谷P4721 【模板】分治 FFT(分治FFT)

    传送门 多项式求逆的解法看这里 我们考虑用分治 假设现在已经求出了$[l,mid]$的答案,要计算他们对$[mid+1,r]$的答案的影响 那么对右边部分的点$f_x$的影响就是$f_x+=\sum_ ...

  7. 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)

    传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...

  8. [题解] Luogu P4721 【模板】分治 FFT

    分治FFT的板子为什么要求逆呢 传送门 这个想法有点\(cdq\)啊,就是考虑分治,在算一段区间的时候,我们把他分成两个一样的区间,然后先做左区间的,算完过后把左区间和\(g\)卷积一下,这样就可以算 ...

  9. luoguP4721 【模板】分治 FFT

    P4721 [模板]分治 FFT 链接 luogu 题目描述 给定长度为 \(n-1\) 的数组 \(g[1],g[2],..,g[n-1]\),求 \(f[0],f[1],..,f[n-1]\),其 ...

随机推荐

  1. 交替最小二乘ALS

    https://www.cnblogs.com/hxsyl/p/5032691.html http://www.cnblogs.com/skyEva/p/5570098.html 1. 基础回顾 矩阵 ...

  2. .net 学习笔记2

      托管代码.非托管代码 语法糖: 写C#代码时,遵守简单的语法.编译时编译器将简单的写法编译成正式的复杂的写法. 如: 上面简写了方法,编译时编译器帮助生成完整的代码   Var 关键字指示 编译器 ...

  3. win10 Xshell5连ubuntu服务器

    相当于ubuntu做服务器,win10远程访问,同一局域网下,完全参考度娘 教你怎么使用xshell远程连接linux服务器 ubuntu系统ifconfig -a查看ip地址,添加到主机那里,连接时 ...

  4. linux常用命令:mv 命令

    mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...

  5. 【Alpha版本】冲刺阶段——Day3

    [Alpha版本]冲刺阶段--Day3 阅读目录 今日进展 问题困难 明日任务 今日贡献量 TODOlist [今日进展] 密码算法方面: 参考了md5/sha1+salt和Bcrypt后,我们决定使 ...

  6. nextjs 服务端渲染请求参数

    Post.getInitialProps = async function (context) { const { id } = context.query const res = await fet ...

  7. 多选插件multiselect.js

    官方网址:http://loudev.com/ html: <html> <head> <link href="path/to/multiselect.css& ...

  8. AtCoder Beginner Contest 084(AB)

    A - New Year 题目链接:https://abc084.contest.atcoder.jp/tasks/abc084_a Time limit : 2sec / Memory limit  ...

  9. jquery遍历获取每一行数据进行对比

    $("#dtlTable tr:gt(0)").each(function(i){ var orderQtyBy = $("input[name='orderQtyBys ...

  10. 写出优质Java代码的4个技巧

    我们平时的编程任务不外乎就是将相同的技术套件应用到不同的项目中去,对于大多数情况来说,这些技术都是可以满足目标的.然而,有的项目可能需要用到一些特别的技术,因此工程师们得深入研究,去寻找那些最简单但最 ...