分治FFT

news/2025/1/9 1:19:47/文章来源:https://www.cnblogs.com/HarlemBlog/p/18660859
更新日志 2025/01/09:开工。

概念

借助分治的思想,在 \(O(n\log^2n)\) 的复杂度内计算下述问题:

给出 \(G(x),x\in[1,n)\),求 \(F(x),x\in[0,n)\)\(F(x)\) 满足:

\[F(0)=0\\ \forall x\in(0,n),F(x)=\sum_{i=1}^xF(x-i)G(i) \]

思路

我们借鉴分治思想,若当前操作区间为 \([l,r]\),令 \(mid=\lfloor\frac{l+r}{2}\rfloor\)

我们先计算出左区间内部的贡献,现在考虑整个左区间对右区间的贡献。

若对 \(F(x)\) 的贡献为 \(w_x\)\(x\in(mid,r]\)):

\[w_x=\sum_{i=l}^{mid}F(i)G(x-i) \]

不妨令此时 \(\forall x\in(mid,r],F(x)=0\),那么这个式子可以改写成:

\[\begin{align*} w_x=&\sum_{i=l}^{x-1}F(i)G(x-i)\\ =&\sum_{i=0}^{x-l-1}F(i+l)G(x-l-i) \end{align*} \]

\(t=x-l-1,A(x)=F(x+l),B(x)=G(x+1)\),则:

\[w_x=\sum_{i=0}^tA(i)B(t-i) \]

这就是一个卷积,\(\text{FFT}/\text{NTT}\) 求解即可。

例题代码

#include<bits/stdc++.h>
using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
typedef double db;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
template <typename Type>
using vec=vector<Type>;
template <typename Type>
using grheap=priority_queue<Type>;
template <typename Type>
using lrheap=priority_queue<Type,vector<Type>,greater<Type> >;
#define fir first
#define sec second
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define chmax(a,b) a=max(a,b)
#define chmin(a,b) a=min(a,b)
#define rep(i,x,y) for(int i=(x);i<=(y);i++)
#define repl(i,x,y) for(int i=(x);i<(y);i++)
#define per(i,x,y) for(int i=(x);i>=(y);i--)const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;const int p=998244353,g=3,gi=332748118;
typedef vec<ll> poly;ll qpow(ll a,ll b){ll res=1;while(b){if(b&1)(res*=a)%=p;(a*=a)%=p;b>>=1;}return res;
}vec<int> r;
void ntt(int lim,poly &a,int type){a.resize(lim);repl(i,0,lim)if(i<r[i])swap(a[i],a[r[i]]);for(int mid=1;mid<lim;mid<<=1){ll w1=qpow((~type)?g:gi,(p-1)/(mid<<1));for(int j=0;j<lim;j+=(mid<<1)){ll w=1;repl(k,0,mid){ll x=a[j+k],y=w*a[j+mid+k]%p;a[j+k]=(x+y)%p;a[j+mid+k]=(x-y+p)%p;w=w*w1%p;}}}
}
poly operator*(poly a,poly b){int lim=1,l=0,len=a.size()+b.size()-1;while(lim<=a.size()+b.size())lim<<=1,l++;r.resize(lim);repl(i,0,lim)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));ntt(lim,a,1);ntt(lim,b,1);poly c(lim);repl(i,0,lim)c[i]=(a[i]*b[i])%p;ntt(lim,c,-1);c.resize(len);ll inv=qpow(lim,p-2);repl(i,0,c.size())(c[i]*=inv)%=p;return c;
}const int N=1e5+5;int n;
ll gg[N];
ll f[N];void solve(int l,int r){if(l==r)return;int m=l+r>>1;solve(l,m);poly a(r-l),b(r-l);rep(i,l,m)a[i-l]=f[i];repl(i,0,r-l)b[i]=gg[i+1];poly c=a*b;rep(x,m+1,r)(f[x]+=c[x-l-1])%=p;solve(m+1,r);
}int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n;repl(i,1,n)cin>>gg[i];f[0]=1;solve(0,n-1);repl(i,0,n)cout<<f[i]<<" ";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/866182.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【流量分析】通过流量查看主机关键信息

主机信息包括:Host信息;操作系统信息;账户信息(域环境);一、如何找到Host信息? 一般通过DHCP或者NBNS两种协议,找到Host信息。NBNS是网络基本输入/输出系统(NetBIOS)名称服务器协议,是TCP/IP上的NetBIOS(NetBT)协议族的一部分,它在基于NetBIOS名称访问的网络上提…

进阶markdown语法

系统复习markdown进阶语法 目录系统复习markdown进阶语法1.文字颜色,字体,大小,文字高亮1.1 文字颜色1.2 文字字体1.3 文字高亮1.4 文字字号2.转义字符3. 表格3.1 基础表格3.2 带有对齐方式表格3.3 复杂表格4.脚注4.1 语法4.2 运用场景5.上下标5.1 上标5.2下标6. Tolist7. 锚…

基础markdown语法

系统复习markdown基础语法 1.分级标题 # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题2.段落 直接回车即为分段 这是第一段 这是第二段这是换行这是第一段 这是第二段 这是换行 3.换行符 如果你需要换>=2行,那么只用回车是不可以的,我…

.NET 响应式编程 System.Reactive 系列文章(三):Subscribe 和 IDisposable 的深入理解

在 Rx 中,Subscribe() 方法返回一个 IDisposable 接口对象,用于手动取消订阅和释放资源。另外,System.Reactive 还提供了不返回 IDisposable 的 Subscribe 重载,这些重载方法通过 CancellationToken 管理订阅的生命周期。在本篇文章中,我们将深入探讨 Subscribe 和 IDispo…

【关节电机专栏】ESP32-S3控制大然电机

如何进行CAN初始化? 以下是ESP32-TWAI-CAN库的CAN总线初始化函数(begin()) bool begin(TwaiSpeed twaiSpeed = TWAI_SPEED_500KBPS, int8_t txPin = -1, int8_t rxPin = -1,uint16_t txQueue = 0xFFFF, uint16_t rxQueue = 0xFFFF,twai_filter_config_t* fConfig = nullptr,…

1.2.7 PMU设计中常见问题的分析解答

PMU设计中常见问题的分析解答 在 PMU(电源管理单元)设计中,常见的问题通常涉及电源性能、热管理、效率、安全性等多个方面。以下是一些常见问题及其分析与解答: 1. 输出电压不稳定 问题:PMU 的输出电压无法达到预期,存在较大的波动。 原因分析:负载变化:当负载发生变化…

1.2.6 PMU电源的散热处理及主要事项

PMU电源的散热处理及主要事项 PMU(Power Management Unit,电源管理单元)作为电子设备中实现电源调节和转换的重要组件,其散热处理至关重要,因为过高的温度会影响性能、可靠性和寿命。以下是 PMU 电源的散热处理方法及主要事项。 一、PMU 电源的散热处理方法选择合适的封装…

1.2 PMU

PMU PMU(Power Management Unit,电源管理单元)是一种集成电路(IC),用于管理和调节电子设备中的电源和电压供应。PMU 的设计旨在提高能源利用效率,减少能量损耗,并确保设备在各种操作条件下的稳定运行。以下是关于 PMU 的详细介绍,包括其功能、组成部分、工作原理和应用…

1. 电源模块

电源模块 电源模块是将电源转换、调节和管理功能集成在一个单元中的电子设备。它们通常用于提供电力和接口,确保电子设备在运行过程中获得稳定的电源供应。以下是关于电源模块的详细讲解,包括其类型、特性、应用等。 1. 什么是电源模块? 电源模块是集成多个组件(如变压器、…

第3章 命名准则

第3章 命名准则 1 大小写约定 1 标识符的大小写规则​DO​: 命名空间 、 类型 、 成员 和 泛型参数 ,使用 PascalCasing 风格命名。‍​DO​​:参数,使用 camelCasing 风格命名。‍标识符 大小写 示例命名空间 Pacal namespace System.Security类型 Pacal public class S…

0. PCB模块

PCB模块 PCB(印刷电路板)模块是在电子设计和应用中非常常见的组件。它们是将电路功能集成到一个统一单元中的关键部分。下面,对 PCB 模块进行详细讲解,包括其定义、类型、应用和设计考虑等方面。 1. 什么是 PCB 模块? PCB 模块是指在印刷电路板上实现特定功能的预制电路板…

MarkDown使用方法

Markdown学习 标题 三级标题 四级标题 字体 Hello,World! Hello,World! Hello,World! Hello,World! 引用好好学习,天天向上分割线图片超链接 [点击跳转到csdn](CSDN - 专业开发者社区) 列表A B CA B C表格名字 性别 生日张三 男 1997.1.1代码 public