参考资料

picks

miskcoo

menci

胡小兔

unname

自为风月马前卒

上面是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学习笔记的更多相关文章

  1. FFT&NTT学习笔记

    具体原理就不讲了qwq,毕竟证明我也不太懂 FFT(快速傅立叶变换)&NTT(快速数论变换) FFT //求多项式乘积 //要求多项式A和多项式B的积多项式C //具体操作就是 //DFT(A ...

  2. FFT/NTT 学习笔记

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

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

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

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

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

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

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

  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. 新项目升级到JFinal3.5之后的改变-着重体验自动依赖注入

    最近,JFinal3.5发布,喜大普奔,我也应JBolt用户的需求,将JBolt进行了升级,实现可配置自动注入开启,支持JFinal3.5的项目生成.具体可以看:JBolt升级日志 这等工作做完后,我 ...

  2. SQL Server数据库所有表重建索引

    USE My_Database;DECLARE @name varchar(100) DECLARE authors_cursor CURSOR FOR  Select [name]   from s ...

  3. IIS 7.0的根文件(applicationHost.config)位置及说明

    位置 C:\Windows\System32\inetsrv\config\applicationHost.config 说明 https://www.microsoft.com/taiwan/tec ...

  4. 唱吧APP产品体验报告

  5. EF生成的实体映射含义

    如图: 组合效果: LEFT JOIN 效果: this.HasOptional(t => t.子表) .WithMany(t => t.主表) .HasForeignKey(d => ...

  6. Servlet中的属性(attribute)和参数(parameter)的区别

    1.引子 初学者对属性(attribute)和参数(parameter)容易搞混.没搞清他们的区别,项目中就可能出现一此莫名其妙的问题. 2.两者的区别 1) 属性(attribute) 属性是在后台 ...

  7. TextView中使用Linkify添加超链接

       首先,在TextView所属xml配置文件中,直接添加android:autoLink特性即可,它支持一个或多个(用分割线)自定义的值:none.web.email.phone或all. 另外, ...

  8. Memcache使用基础

    Memcached的特点:     协议简单     基于libevent的事件处理     内置内存存储方式     memcached不互相通信的分布式   1.协议简单:     使用简单的基于 ...

  9. DROP LANGUAGE - 删除一个过程语言

    SYNOPSIS DROP [ PROCEDURAL ] LANGUAGE name [ CASCADE | RESTRICT ] DESCRIPTION 描述 DROP LANGUAGE 将删除曾注 ...

  10. C09 指针

    目录 指针相关概念 指针变量 null指针 指针的算术运算 指针数组 指向指针的指针 传递指针给函数 从函数返回指针 指针相关概念 变量 如果在程序中定义了一个变量,在对程序进行编译时,系统就会为这个 ...