具体原理就不讲了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. Codeforces Round #499 (Div. 2) C.FLY 数学推导_逆推

    本题应该是可以使用实数二分的,不过笔者一直未调出来,而且发现了一种更为优美的解法,那就是逆推. 首先,不难猜到在最优解中当飞船回到 111 号节点时油量一定为 000, 这就意味着减少的油量等于减少之 ...

  2. Robot Framework自动化框架搭建的步骤

    我把自己之前搭建Robot Framework自动化测试框架的步骤整理了一下,感兴趣的同学可以参考一下.   Robot Framework自动化测试框架+ 可视化编辑工具RIDE+Selenium2 ...

  3. BZOJ 3672 [NOI2014]购票 (凸优化+树剖/树分治)

    题目大意: 略 题面传送门 怎么看也是一道$duliu$题= = 先推式子,设$dp[x]$表示到达$x$点到达1节点的最小花费 设$y$是$x$的一个祖先,则$dp[x]=min(dp[y]+(di ...

  4. Jquery JS 全局变量

    window["a1"]="abc";window["b1"]=5;

  5. HDU3001 Traveling (状压dp+三进制+Tsp问题总结)

    (1)这道题最多可以走两次,所以有0, 1, 2三种状态,所以我们要用三进制 如果要用三进制,就要自己初始化两个数组, 一个是3的n次方,一个是三进制数的第几位的数字是什么 void init() { ...

  6. js数组并集,交集,差集

    js数组并集,交集,差集的计算方式汇总 一. new Set 方式实现 这种方式实现起来比较简单,原理就是参考new Set可以去重的功能 ,关于去重可以点击 https://www.haorooms ...

  7. 【 【henuacm2016级暑期训练】动态规划专题 G】 Palindrome pairs

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先用枚举回文串中点的方法. 得到这个字符串中出现的所有的回文. 得到他们的左端点以及右端点. 整理成一个pair<int,in ...

  8. 记一次BootStrap的使用

    效果图如下: 一.简介: 什么是Bootstrap?  Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架. 什么是响应式布局? 引用一句Bootstrap的标题语 “Boots ...

  9. open函数详解

    转载:https://www.cnblogs.com/frank-yxs/p/5925574.html open函数用来在进程中打开文件,如果成功则返回一个文件描述符fd. ============= ...

  10. shell脚本学习之ubuntu删除多余内核

    #!/bin/bash #定期删除内核 #存储命令输出cmd_output=`commands` uname_output=$(uname -r) kernel_output=`dpkg --list ...