FFT&NTT学习笔记
具体原理就不讲了qwq,毕竟证明我也不太懂
FFT(快速傅立叶变换)&NTT(快速数论变换)
FFT
//求多项式乘积
//要求多项式A和多项式B的积多项式C
//具体操作就是
//DFT(A),DFT(B)->暴力乘积->拉格朗日插值(即IDFT(C))->C
//其中DFT表示离散傅里叶变换
//通俗的来说就是用点值表示多项式
//使用神秘单位复数根将时间复杂度降至O(nlogn)
//ps:但是常数巨大
//pps:应用非常广泛,非常多题目都要fft or ntt优化,板子一定要背熟
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define pw(n) (1<<n)
using namespace std;
const double pi=acos(-);
struct complex{
double a,b;
complex(double _a=,double _b=){
a=_a;
b=_b;
}
friend complex operator +(complex x,complex y){return complex(x.a+y.a,x.b+y.b);}
friend complex operator -(complex x,complex y){return complex(x.a-y.a,x.b-y.b);}
friend complex operator *(complex x,complex y){return complex(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a);}
friend complex operator *(complex x,double y){return complex(x.a*y,x.b*y);}
friend complex operator /(complex x,double y){return complex(x.a/y,x.b/y);}
}a[],b[];
int n,m,bit,bitnum=,rev[pw()];
void getrev(int l){//Reverse
for(int i=;i<pw(l);i++){
rev[i]=(rev[i>>]>>)|((i&)<<(l-));
}
}
void FFT(complex *s,int op){
for(int i=;i<bit;i++)if(i<rev[i])swap(s[i],s[rev[i]]);
for(int i=;i<bit;i<<=){
complex w(cos(pi/i),op*sin(pi/i));
for(int p=i<<,j=;j<bit;j+=p){//Butterfly
complex wk(,);
for(int k=j;k<i+j;k++,wk=wk*w){
complex x=s[k],y=wk*s[k+i];
s[k]=x+y;
s[k+i]=x-y;
}
}
}
if(op==-){
for(int i=;i<=bit;i++){
s[i]=s[i]/(double)bit;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%lf",&a[i].a);
for(int i=;i<=m;i++)scanf("%lf",&b[i].a);
m+=n;
for(bit=;bit<=m;bit<<=)bitnum++;
getrev(bitnum);
FFT(a,);
FFT(b,);
for(int i=;i<=bit;i++)a[i]=a[i]*b[i];
FFT(a,-);
for(int i=;i<=m;i++)printf("%d ",(int)(a[i].a+0.5));
return ;
}
NTT
//费马数数论变换
//大家觉得998244353好还是1004535809好?^_^
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define pw(n) (1<<n)
using namespace std;
const int N=,P=,g=;//或P=1004535809
int n,m,bit,bitnum=,a[N+],b[N+],rev[N+];
void getrev(int l){
for(int i=;i<pw(l);i++){
rev[i]=(rev[i>>]>>)|((i&)<<(l-));
}
}
int fastpow(int a,int b){
int ans=;
for(;b;b>>=,a=1LL*a*a%P){
if(b&)ans=1LL*ans*a%P;
}
return ans;
}
void NTT(int *s,int op){
for(int i=;i<bit;i++)if(i<rev[i])swap(s[i],s[rev[i]]);
for(int i=;i<bit;i<<=){
int w=fastpow(g,(P-)/(i<<));
for(int p=i<<,j=;j<bit;j+=p){
int wk=;
for(int k=j;k<i+j;k++,wk=1LL*wk*w%P){
int x=s[k],y=1LL*s[k+i]*wk%P;
s[k]=(x+y)%P;
s[k+i]=(x-y+P)%P;
}
}
}
if(op==-){
reverse(s+,s+bit);
int inv=fastpow(bit,P-);
for(int i=;i<bit;i++)a[i]=1LL*a[i]*inv%P;
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<=m;i++)scanf("%d",&b[i]);
m+=n;
for(bit=;bit<=m;bit<<=)bitnum++;
getrev(bitnum);
NTT(a,);
NTT(b,);
for(int i=;i<bit;i++)a[i]=1LL*a[i]*b[i]%P;
NTT(a,-);
for(int i=m;i>=;i--)printf("%d ",a[i]);
return ;
}
FFT&NTT学习笔记的更多相关文章
- FFT/NTT 学习笔记
0. 前置芝士 基础群论 复数 \(\mathbb C = \mathbb R[x^2+1]\) 则有 \(i^2+1=(-i)^2+1=0\),\(i \in \mathbb C - \mathbb ...
- FFT和NTT学习笔记_基础
FFT和NTT学习笔记 算法导论 参考(贺) http://picks.logdown.com/posts/177631-fast-fourier-transform https://blog.csd ...
- FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅲ
第三波,走起~~ FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ 单位根反演 今天打多校时 1002 被卡科技了 ...
- FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ
众所周知,tzc 在 2019 年(12 月 31 日)就第一次开始接触多项式相关算法,可到 2021 年(1 月 1 日)才开始写这篇 blog. 感觉自己开了个大坑( 多项式 多项式乘法 好吧这个 ...
- FFT、NTT学习笔记
参考资料 picks miskcoo menci 胡小兔 unname 自为风月马前卒 上面是FFT的,学完了就来看NTT吧 原根 例题:luogu3803 fft优化后模板 #include < ...
- FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ
因为垃圾电脑太卡了就重开了一个... 前传:多项式Ⅰ u1s1 我预感还会有Ⅲ 多项式基础操作: 例题: 26. CF438E The Child and Binary Tree 感觉这题作为第一题还 ...
- 快速傅里叶变换(FFT)学习笔记(未完待续)
目录 参考资料 FFT 吹水 例题 普通做法 更高大尚的做法 定义与一部分性质 系数表达式 点值表达式 点值相乘??? 卷积 复数 单位根 DFT IDFT 蝴蝶迭代优化 单位根求法 实现.细节与小优 ...
- NTT学习笔记
和\(FFT\)相对应的,把单位根换成了原根,把共轭复数换成了原根的逆元,最后输出的时候记得乘以原\(N\)的逆元即可. #include <bits/stdc++.h> using na ...
- NTT 学习笔记
引入 \(\tt NTT\) 和 \(\tt FFT\) 有什么不一样呢? 就是 \(\tt NTT\) 是可以用来取模的,而且没有复数带来的精度误差. 最最重要的是据说 \(\tt NTT\) 常数 ...
随机推荐
- codeforces 277 A Learning Languages 【DFS 】
n个人,每个人会一些语言,两个人只要有会一门相同的语言就可以交流,问为了让这n个人都交流,至少还得学多少门语言 先根据n个人之间他们会的语言,建边 再dfs找出有多少个联通块ans,再加ans-1条边 ...
- C#基础篇之语言和框架介绍
1.如何描述C#和.NET的关系? .Net的是平台,C#是为了微软公司为了.NET平台开发的面向对象语言. 2.C#能做什么? (1)C#.NET做窗体应用开发,Web开发中可以通过WCF编写Web ...
- luogu P4245 【模板】任意模数NTT MTT
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...
- underscore的简单了解
1.underscore:一个封装好的js工具库,它提供了一整套函数式编程的使用功能,但是没有扩展任何js内置对象.它解决了这个问题:如果我面对一个空白的HTML,并希望立即开始工作,我需要什么? 2 ...
- HDU 1086 You can Solve a Geometry Problem too( 判断线段是否相交 水题 )
链接:传送门 题意:给出 n 个线段找到交点个数 思路:数据量小,直接暴力判断所有线段是否相交 /*************************************************** ...
- Consider defining a bean of type 'XX.XX.XX.XX.mapper.XXMapper' in your configuration.
今天构建一个springboot 项目,采用mybatis+mysql 然后就出现了这种错误....浪费我半天时间 Description: Field loginLogMapper in com.g ...
- dfs序题集
dfs序可以维护一个子树内的信息 需要记录dfs进的时间以及所有子树都遍历完的时间 void dfs(int u, int fa) { L[u] = ++id; for(int i = head[u] ...
- [luogu] P4040 [AHOI2014/JSOI2014]宅男计划(贪心)
P4040 [AHOI2014/JSOI2014]宅男计划 题目背景 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY不得不依靠叫外卖来维持生计. 题目描述 外卖店一共有N种食物, ...
- Http请求和相应模式(B/S)(1)
B/S模式 服务器端的接受数据 :浏览器端 表单格式 <form></form> GET:请求方式, /index.html Web浏览器上的资源路径 uname=bjxt& ...
- 洛谷——P3258 [JLOI2014]松鼠的新家
https://www.luogu.org/problem/show?pid=3258 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到 ...