P4721 【模板】分治 FFT

题目背景

也可用多项式求逆解决。

题目描述

给定长度为 $n-1$ 的数组 $g[1],g[2],..,g[n-1]$,求 $f[0],f[1],..,f[n-1]$,其中

$$f[i]=\sum_{j=1}^if[i-j]g[j]$$

边界为 $f[0]=1$ 。答案模 $998244353$ 。

输入输出格式

输入格式:

第一行一个正整数 $n$ 。

第二行共 $n-1$ 个非负整数 $g[1],g[2],..,g[n-1]$,用空格隔开。

输出格式:

一行共 $n$ 个非负整数,表示 $f[0],f[1],..,f[n-1]$ 模 $998244353$ 的值。

输入输出样例

输入样例#1:
复制

4
3 1 2
输出样例#1:
复制

1 3 10 35
输入样例#2:
复制

10
2 456 32 13524543 998244352 0 1231 634544 51
输出样例#2:
复制

1 2 460 1864 13738095 55389979 617768468 234028967 673827961 708520894

说明

$2\leq n\leq 10^5$

$0\leq g[i]<998244353$

\(g[0]=0\)这应该是具体的题目推出来的通性,否则自己就可以反复更新自己了。

Great_Influence的分治FFT

发现题目的要求类似于卷积,于是考虑使用FFT。但是后面的数字基于前面的数字,无法快速计算,时间复杂度退化至\(O(n^2)\)。于是我们考虑将类似的转移同时进行,来节省复杂度。

考虑利用分治。

假设我们求出了\(l\to mid\)的答案,要求这些点对\(mid+1\to r\)的影响,那么对右半边点\(f[x]\)的贡献为:

\[f[x]=\sum_{i=l}^{mid} f[i] * g[x-i]
\]

这部分可以利用卷积来快速计算。计算完以后,答案直接加到答案数组就可以了。

需要注意的是,如果要求左边点对右边点的影响,首先整个区间以左对该区间的贡献应该先求出。所以分治过程为先分治左边,再求出中间,最后递归右边。

时间复杂度\(O(n\log^2n)\)。

有一个卡常技巧,就是可以发现你计算的时候只会用到 \(md-l\sim r-l\) 的这一部分,前半部分不需要管。因此,直接用循环卷积对它进行处理,做乘法的时候不必做长度为 \(1.5(r-l+1)\) 的,只需要做长度为 \(r-l+1\) 的就可以了。

所谓循环卷积呢,就是FFT溢出的值会从\(0\)开始填上。实际卷出\(1.5(r-l+1)\),超出部分填到了前\(0.5(r-l+1)\),而我们需要的值是中间一段,所以不影响。

void num_trans(polynomial&a,int inverse){
int limit=a.size(),len=log2(limit);
static vector<int> bit_rev;
if(bit_rev.size()!=limit){
bit_rev.resize(limit);
for(int i=0;i<limit;++i) bit_rev[i]=bit_rev[i>>1]>>1|(i&1)<<(len-1);
}
for(int i=0;i<limit;++i)if(i<bit_rev[i]) swap(a[i],a[bit_rev[i]]);
for(int step=1;step<limit;step<<=1){
int gn=fpow(inverse==1?g:g_inv,(mod-1)/(step<<1));
for(int even=0;even<limit;even+=step<<1){
int odd=even+step,gk=1;
for(int k=0;k<step;++k,gk=mul(gk,gn)){
int t=mul(gk,a[odd+k]);
a[odd+k]=add(a[even+k],mod-t),a[even+k]=add(a[even+k],t);
}
}
}
if(inverse==-1){
int lim_inv=fpow(limit,mod-2);
for(int i=0;i<limit;++i) a[i]=mul(a[i],lim_inv);
}
}
void solve(polynomial&f,polynomial&g,int l,int r){
if(l==r){
if(!l) f[l]=1;
return;
}
int mid=(l+r)>>1;
solve(f,g,l,mid);
polynomial a(f.begin()+l,f.begin()+mid+1),b(g.begin(),g.begin()+r-l+1); // extract x^l
int limit=1<<int(ceil(log2(r-l+1)));
a.resize(limit),num_trans(a,1);
b.resize(limit),num_trans(b,1);
for(int i=0;i<limit;++i) a[i]=mul(a[i],b[i]);
num_trans(a,-1);
for(int i=mid+1;i<=r;++i) f[i]=add(f[i],a[i-l]);
solve(f,g,mid+1,r);
} int main(){
int n=read<int>();
polynomial f(n),g(n);
for(int i=1;i<n;++i) read(g[i]);
solve(f,g,0,n-1);
for(int i=0;i<n;++i) printf("%d ",f[i]);
return 0;
}

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

  1. 洛谷.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 ...

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

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

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

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

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

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

  5. 【洛谷4721】【模板】分治FFT(CDQ分治_NTT)

    题目: 洛谷 4721 分析: 我觉得这个 "分治 FFT " 不能算一种特殊的 FFT ,只是 CDQ 分治里套了个用 FFT (或 NTT)计算的过程,二者是并列关系而不是偏正 ...

  6. luoguP4721 【模板】分治 FFT

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

  7. P4721【模板】分治 FFT

    瞎扯 虽然说是FFT但是还是写了一发NTT(笑) 然后忘了IDFT之后要除个n懵逼了好久 以及递归的时候忘了边界无限RE 思路 朴素算法 分治FFT 考虑到题目要求求这样的一个式子 \[ F_x=\S ...

  8. [洛谷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^ ...

  9. 洛谷 4721 【模板】分治 FFT——分治FFT / 多项式求逆

    题目:https://www.luogu.org/problemnew/show/P4721 分治FFT:https://www.cnblogs.com/bztMinamoto/p/9749557.h ...

随机推荐

  1. 面试之leetcode分治-求众数,x幂等

    1 leetcode50 计算 x 的 n 次幂函数. 实现 pow(x, n) ,即计算 x 的 n 次幂函数. (1)调用库函数 (2)暴力o(N) (3)分治 xxxxxx.......x    ...

  2. HDU6608-Fansblog(Miller_Rabbin素数判定,威尔逊定理应用,乘法逆元)

    Problem Description Farmer John keeps a website called ‘FansBlog’ .Everyday , there are many people ...

  3. LeetCode 556. 下一个更大元素 III(Next Greater Element III)

    556. 下一个更大元素 III 556. Next Greater Element III 题目描述 给定一个 32 位正整数 n,你需要找到最小的 32 位整数,其与 n 中存在的位数完全相同,并 ...

  4. [转帖]VMware vSphere 6 序列号大全

    VMware vSphere 6 序列号大全 https://blog.csdn.net/sj349781478/article/details/82378244   经过测试ESXI6.5也可以使用 ...

  5. 2.RabbitMQ 的可靠性消息的发送

      本篇包含 1. RabbitMQ 的可靠性消息的发送 2. RabbitMQ 集群的原理与高可用架构的搭建 3. RabbitMQ 的实践经验   上篇包含 1.MQ 的本质,MQ 的作用 2.R ...

  6. 初学者用pycharm创建一个django项目和一个app时需要注意的事项

    如何新建一个djiango项目: 1.在pycharm中点击File,选择new project,点击djiango,在右面的Location中将untitile改为你的项目名,其余部分注意见下图: ...

  7. Logrotate滚动openresty日志

    一.摘要 Linux服务器上我们用Logrotate来分割归档日志文件,结合crond我们可以指定每天在某个时间自动整理日志等文档.本文主要说明了Centos下Logrotate的使用和配置的方法. ...

  8. CCF 2016-04-2 俄罗斯方块

    CCF 2016-04-2 俄罗斯方块 题目 问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏. 游戏在一个15行10列的方格图上进行,方格图上的每一个格子可能已经放置了方块,或者 ...

  9. 可分离滤波器设计高斯滤波 CUDA程序优化, 实验记录

    环境:RTX2060 ,1920X1080p ,循环10次, kernal_size=8 一 .测试前128个线程拷贝到dst数据的性能  ,只测试行卷积, block=(128+2r)X1 1. 使 ...

  10. C# Attribute 名称和使用的问题

    如果定义Attribute时, 名字是以Attribute结尾的, 在使用的时候, 就可以省略Attribute, 直接写前面的名字, 但是这样真的好吗? 自以为帮程序员省了一个单词, 然而 真理不再 ...