具体原理就不讲了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学习笔记的更多相关文章

  1. FFT/NTT 学习笔记

    0. 前置芝士 基础群论 复数 \(\mathbb C = \mathbb R[x^2+1]\) 则有 \(i^2+1=(-i)^2+1=0\),\(i \in \mathbb C - \mathbb ...

  2. FFT和NTT学习笔记_基础

    FFT和NTT学习笔记 算法导论 参考(贺) http://picks.logdown.com/posts/177631-fast-fourier-transform https://blog.csd ...

  3. FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅲ

    第三波,走起~~ FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ 单位根反演 今天打多校时 1002 被卡科技了 ...

  4. FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ

    众所周知,tzc 在 2019 年(12 月 31 日)就第一次开始接触多项式相关算法,可到 2021 年(1 月 1 日)才开始写这篇 blog. 感觉自己开了个大坑( 多项式 多项式乘法 好吧这个 ...

  5. FFT、NTT学习笔记

    参考资料 picks miskcoo menci 胡小兔 unname 自为风月马前卒 上面是FFT的,学完了就来看NTT吧 原根 例题:luogu3803 fft优化后模板 #include < ...

  6. FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ

    因为垃圾电脑太卡了就重开了一个... 前传:多项式Ⅰ u1s1 我预感还会有Ⅲ 多项式基础操作: 例题: 26. CF438E The Child and Binary Tree 感觉这题作为第一题还 ...

  7. 快速傅里叶变换(FFT)学习笔记(未完待续)

    目录 参考资料 FFT 吹水 例题 普通做法 更高大尚的做法 定义与一部分性质 系数表达式 点值表达式 点值相乘??? 卷积 复数 单位根 DFT IDFT 蝴蝶迭代优化 单位根求法 实现.细节与小优 ...

  8. NTT学习笔记

    和\(FFT\)相对应的,把单位根换成了原根,把共轭复数换成了原根的逆元,最后输出的时候记得乘以原\(N\)的逆元即可. #include <bits/stdc++.h> using na ...

  9. NTT 学习笔记

    引入 \(\tt NTT\) 和 \(\tt FFT\) 有什么不一样呢? 就是 \(\tt NTT\) 是可以用来取模的,而且没有复数带来的精度误差. 最最重要的是据说 \(\tt NTT\) 常数 ...

随机推荐

  1. 第一次接触Arduino

    1.百度百科: Arduino包含两个主要的部分:硬件部分是可以用来做电路连接的Arduino电路板:另外一个则是 Arduino IDE,你的计算机中的程序开发环境.你只要在IDE中编写程序代码,将 ...

  2. Debian下签名无法验证

    又收集到的新方法 gpg --keyserver  subkeys.pgp.net --recv-keys AED4B06F473041FA  && apt-key add /root ...

  3. Python介绍与学习

    Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年. Python是纯粹的自由软件, 源代码和解释器CPy ...

  4. CF894E Ralph and Mushrooms_强连通分量_记忆化搜索_缩点

    Code: #include<cstdio> #include<stack> #include<cstring> using namespace std; cons ...

  5. JAVA导出csv出现0.00E+00

    导出csv出现 0.00E+00的问题,打印其值为0E-8:这是因为数据表中无对应数据(decimal),查询结果则为 0e-8. 出现的字段是多个字段相加产生的和,所以这里调用了一个相加的方法.在相 ...

  6. Redis字符串(STRING)中BIT相关命令

    上篇文章我们对STRING数据类型中一些基本的命令进行了介绍,但是没有涉及到BIT相关的命令,本文我们就来看看几个和BIT相关的命令. 本文是Redis系列的第四篇文章,了解前面的文章有助于更好的理解 ...

  7. # quill-image-extend-module :实现vue-quill-editor图片上传,复制粘贴,拖拽

    改造vue-quill-editor: 结合element-ui上传图片到服务器 quill-image-extend-module vue-quill-editor的增强模块, 功能: 提供图片上传 ...

  8. s5pv210 fimc 之 fimc-dev.c

    fimc-dev.c 是Samsung FIMC 设备的V4L2 驱动.上层应用直接操作这个设备,进行capture,图片处理,以及overlay输出 http://blog.csdn.net/cxw ...

  9. keil5下载程序时出现“internal command error”解决方法

    今天下载的时候,插入下载器,查看Debug可用看到“internal command error”,一直找不到原因,后来查看上一个工程才发现,上一个程序禁用了Seral Wire 引脚,导致的. 解决 ...

  10. sql server 与 mysql在自定以数据类型的区别

    sql server   中可以使用 create  TYPE postal_code FORM varchar(6) not null; 用于限定邮编的数据位数,他基于varchar数据类型 注意: ...