FFT、NTT学习笔记
参考资料
上面是FFT的,学完了就来看NTT吧
例题:luogu3803
fft优化后模板
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, m, lim=1, rev[2100005];
const double PI=acos(-1.0);
struct Complex{
double x, y;
Complex(double xx=0.0, double yy=0.0){
x = xx;
y = yy;
}
Complex operator+(const Complex &u)const{
return Complex(x+u.x, y+u.y);
}
Complex operator-(const Complex &u)const{
return Complex(x-u.x, y-u.y);
}
Complex operator*(const Complex &u)const{
return Complex(x*u.x-y*u.y, x*u.y+y*u.x);
}
}a[2100005], b[2100005];
template<typename T> void rn(T &x){
x = 0;
char ch=getchar();
while(ch<'0' || ch>'9') ch = getchar();
while(ch>='0' && ch<='9'){
x = x * 10 + ch - '0';
ch = getchar();
}
}
void fft(Complex a[], int opt){
for(int i=0; i<lim; i++)
if(i<rev[i])
swap(a[i], a[rev[i]]);
for(int i=2; i<=lim; i<<=1){
int tmp=i>>1;
Complex wn=Complex(cos(PI*2.0/i), opt*sin(PI*2.0/i));
for(int j=0; j<lim; j+=i){
Complex w=Complex(1.0, 0.0);
for(int k=0; k<tmp; k++){
Complex tmp1=a[j+k], tmp2=w*a[j+k+tmp];
a[j+k] = tmp1 + tmp2;
a[j+k+tmp] = tmp1 - tmp2;
w = w * wn;
}
}
}
if(opt==-1)
for(int i=0; i<lim; i++)
a[i].x /= lim;
}
int main(){
cin>>n>>m;
for(int i=0; i<=n; i++) rn(a[i].x);
for(int i=0; i<=m; i++) rn(b[i].x);
int tmpcnt=0;
while(lim<=n+m) lim <<= 1, tmpcnt++;
for(int i=0; i<lim; i++)
rev[i] = (rev[i>>1]>>1) | ((i&1)<<(tmpcnt-1));
fft(a, 1);
fft(b, 1);
for(int i=0; i<lim; i++)
a[i] = a[i] * b[i];
fft(a, -1);
for(int i=0; i<=n+m; i++)
printf("%d ", (int)(a[i].x+0.5));
printf("\n");
return 0;
}
NTT
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n, m, a[2100005], b[2100005], lim=1, limcnt, rev[2100005];
const int mod=998244353, gg=3, gi=332748118;
void rn(int &x){
char ch=getchar();
x = 0;
while(ch<'0' || ch>'9') ch = getchar();
while(ch>='0' && ch<='9'){
x = x * 10 + ch - '0';
ch = getchar();
}
}
int ksm(int a, int b){
int re=1;
while(b){
if(b&1) re = (ll)re * a % mod;
a = (ll)a * a % mod;
b >>= 1;
}
return re;
}
void ntt(int a[], int opt){
for(int i=0; i<lim; i++)
if(i<rev[i])
swap(a[i], a[rev[i]]);
for(int i=2; i<=lim; i<<=1){
int tmp=i>>1, wn=ksm(opt==1?gg:gi, (mod-1)/i);
for(int j=0; j<lim; j+=i){
int w=1;
for(int k=0; k<tmp; k++){
int tmp1=a[j+k], tmp2=(ll)w*a[j+k+tmp]%mod;
a[j+k] = (tmp1 + tmp2) % mod;
a[j+k+tmp] = (tmp1 - tmp2 + mod) % mod;
w = (ll)w * wn % mod;
}
}
}
if(opt==-1){
int inv=ksm(lim, mod-2);
for(int i=0; i<lim; i++)
a[i] = (ll)a[i] * inv % mod;
}
}
int main(){
cin>>n>>m;
for(int i=0; i<=n; i++) rn(a[i]);
for(int i=0; i<=m; i++) rn(b[i]);
while(lim<=n+m) lim <<= 1, limcnt++;
for(int i=0; i<lim; i++)
rev[i] = (rev[i>>1]>>1) | ((i&1)<<(limcnt-1));
ntt(a, 1);
ntt(b, 1);
for(int i=0; i<lim; i++)
a[i] = (ll)a[i] * b[i] % mod;
ntt(a, -1);
for(int i=0; i<=n+m; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
递归版裸fft没什么优化
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, m;
const double PI=acos(-1.0);
struct Complex{
double x, y;
Complex(double xx=0.0, double yy=0.0){
x = xx;
y = yy;
}
Complex operator+(const Complex &u)const{
return Complex(x+u.x, y+u.y);
}
Complex operator-(const Complex &u)const{
return Complex(x-u.x, y-u.y);
}
Complex operator*(const Complex &u)const{
return Complex(x*u.x-y*u.y, x*u.y+y*u.x);
}
}a[4000005], b[4000005], buf[4000005];
void fft(Complex a[], int lim, int opt){
if(lim==1) return ;
int tmp=lim/2;
for(int i=0; i<tmp; i++){
buf[i] = a[2*i];
buf[i+tmp] = a[2*i+1];
}
for(int i=0; i<lim; i++)
a[i] = buf[i];
fft(a, tmp, opt);
fft(a+tmp, tmp, opt);
Complex wn=Complex(cos(PI*2.0/lim), opt*sin(PI*2.0/lim)), w=Complex(1.0, 0.0);
for(int i=0; i<tmp; i++){
buf[i] = a[i] + w * a[i+tmp];
buf[i+tmp] = a[i] - w * a[i+tmp];
w = w * wn;
}
for(int i=0; i<lim; i++)
a[i] = buf[i];
}
int main(){
cin>>n>>m;
for(int i=0; i<=n; i++) scanf("%lf", &a[i].x);
for(int i=0; i<=m; i++) scanf("%lf", &b[i].x);
int lim=1;
while(lim<=n+m) lim <<= 1;
fft(a, lim, 1);
fft(b, lim, 1);
for(int i=0; i<=lim; i++)
a[i] = a[i] * b[i];
fft(a, lim, -1);
for(int i=0; i<=n+m; i++)
printf("%d ", (int)(a[i].x/lim+0.5));
printf("\n");
return 0;
}
FFT、NTT学习笔记的更多相关文章
- FFT&NTT学习笔记
具体原理就不讲了qwq,毕竟证明我也不太懂 FFT(快速傅立叶变换)&NTT(快速数论变换) FFT //求多项式乘积 //要求多项式A和多项式B的积多项式C //具体操作就是 //DFT(A ...
- 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复习笔记&多项式&生成函数学习笔记Ⅱ
因为垃圾电脑太卡了就重开了一个... 前传:多项式Ⅰ 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\) 常数 ...
随机推荐
- spring中自动装配bean
首先用@Component注解类: package soundsystem: import org.springframework.stereotype.Component; @Component p ...
- js控制语句
1 条件判断语句 条件语句用于基于不同的条件来执行不同的动作. 1.1if 语句 if (condition){ 当条件为 true 时执行的代码} 1.2if...else 语句 if (co ...
- OPEN SQL
OPEN SQL 1.SELECT .INSERT.UPDATE.DELETE.MODIFYSELECT 命令包含如下从句:SELECT: 需要查询资料库指定表的那些列,是一行还是多行INTO: 查询 ...
- jquery实现的导航栏切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Android--View事件传递
Android--View事件传递 View事件传递首先要明白以下要素: 事件就是MotionEvent.该对象包含了传递的事件中的所有信息 事件的来源是Window(即PhoneWindow),包含 ...
- 【extjs6学习笔记】Mastering Ext JS, 2nd Edition
我不知道在别人看来,我是什么样的人:但在我自己看来,我不过就象是一个在海滨玩耍的小孩,为不时发现比寻常更为光滑的一块卵石或比寻常更为美丽的一片贝壳而沾沾自喜,而对于展现在我面前的浩瀚的真理的海洋,却全 ...
- IT部门域事件与业务分析
IT event--->system--->IT dept |--------------->IT dept |--------------->system 域事件分类: 直接 ...
- 在Windows Server 2012中搭建SQL Server 2012故障转移集群
OK~ WSFC 2012 R2 年度盛宴开始~ 在本文中,老王将用一系列的场景,把动态仲裁,动态见证,票数调整,LowerQuorumPriorityNodeID,阻止仲裁等群集仲裁技术串起来,完成 ...
- win10 KMS激活
运行 输入以管理员权限输入CMD 如果已安装密匙先卸载,没有的话可以跳过 slmgr -upk 卸载密匙命令 输入对应版密匙以及KMS地址激活 1.键入命令:slmgr -ipk XXXXX-XXXX ...
- Integer的一个小问题
看面试题的时候看到这道题: public class Demo { public static void main(String[] args) { Integer i1 = 128; Integer ...