做了全家桶然后写了几道入门题。

FFT.ref

NTT.ref

Luogu4238 【模板】多项式求逆

Link

套牛顿迭代完事。有一个细节问题是:这次运算多项式有几项就只赋几项的值,其他位置(次数大于n次的项在\(mod\ {x^n}\)意义下当然为0)一定要设成0(即清空数组),否则会计算错误。

Luogu5205 【模板】多项式开根

Link

开根也是牛顿迭代的问题。运算的时候时刻注意是在\(mod\ {x^n}\)意义下进行的,这决定了多项式取的位数。

tips:两个长度为n(2的次幂)的多项式相乘,本来应该要在长度为2n下运算,如果在长度为n下运算,那么NTT会起到循环卷积的效果,即后面n项的贡献会平移到前n项来。

Luogu4725 【模板】多项式ln

Link

求导秒掉 求导的时候要注意链式法则。求导和积分最高位也是m-1。

Luogu4726 【模板】多项式exp

Link

牛顿迭代。

Luogu5245 【模板】多项式快速幂

Link

\(B(x)=A^k(x)\ \rightarrow B(x)=e^{k*ln(A(x))}\)。

[SDOI2015]序列统计

Link

\(f[i*2][c]= {\sum_{a*b\%m\equiv c}} {f[i][a]*f[i][b]}\)。快速幂一个log,每层转移是\(m^2\)的。转移次数不太好优化,考虑优化每层转移速度。有一个很妙的做法是两边求log,(用原根作为log的底数),此时式子就变成:\(f[i*2][c]= {\sum_{log(a)+log(b)\%m\equiv log(c)}} {f[i][a]*f[i][b]}\),一个平凡的卷积,NTT硬套完事儿。另外普通快速幂就行了,不需要用到ln+exp。

[ZJOI2014]力

Link

IDFT求完后除以n,此处n指的是化为2的次幂的那个n!另外是精度问题!!!假设要卷积的两个多项式F和G,F的系数均在[\(10^{-5},10^{-6}\)]之间,而G的系数均在[\(10^5,10^6\)]之间。直接做两遍DFT+一遍IDFT,涉及的精度跨度是\(10^{12}\),没毛病。但是!!如果用三步并两步优化(一遍DFT+一遍IDFT)的话,涉及的精度跨度上限就是平方,也就是\(10^{24}\)的,而double小数点后有效位数是15~16位,GG。像是这道题如果用了三步并两步,那么就可以获得0分的好成绩(烟)。

板子

FFT

注意idft的时候/n,实部和虚部都要除。

#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=(a),_ed=(b);i<=_ed;++i)
#define DREP(i,a,b) for(int i=(a),_ed=(b);i>=_ed;--i)
typedef long long ll;
inline int read(){
register int x=0,f=1;register char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
while(isdigit(ch)){x=x*10+(ch^'0');ch=getchar();}
return f?x:-x;
} const int N=(1<<21)+5;
const double Pi=acos(-1.0);
int n,m,trans[N];
struct cmplx{
double x,y;
inline cmplx(double _x=0,double _y=0):x(_x),y(_y){}
inline cmplx operator+(const cmplx& t){return (cmplx){x+t.x,y+t.y};}
inline cmplx operator-(const cmplx& t){return (cmplx){x-t.x,y-t.y};}
inline cmplx operator*(const cmplx& t){return (cmplx){x*t.x-y*t.y,x*t.y+y*t.x};}
inline void operator/=(const int &t){x/=t,y/=t;}
};
cmplx f[N],g[N],w[N]; void FFT(cmplx* f,int n){
REP(i,0,n-1)if(i<trans[i])swap(f[i],f[trans[i]]);
for(int len=2,d=1;len<=n;d=len,len<<=1)
for(int p=0;p<n;p+=len)
for(int i=p;i<p+d;++i){
cmplx t=f[i+d]*w[d+i-p];
f[i+d]=f[i]-t;f[i]=f[i]+t;
}
}
void times(cmplx* f,cmplx* g,int m1,int m2){
int n=1;for(;n<m1+m2-1;n<<=1);
REP(i,0,n-1)trans[i]=(trans[i>>1]>>1)|(i&1?(n>>1):0);
for(int len=2,d=1;len<=n;d=len,len<<=1){
cmplx nw=cmplx(1,0),e=cmplx(cos(2*Pi/len),sin(2*Pi/len));
for(int i=0;i<d;++i,nw=nw*e)w[d+i]=nw;
}
FFT(f,n),FFT(g,n);
REP(i,0,n-1)f[i]=f[i]*g[i];
FFT(f,n);
reverse(f+1,f+n);
REP(i,0,n-1)f[i]/=n;
} int main(){
//freopen("in.in","r",stdin);
n=read()+1,m=read()+1;
REP(i,0,n-1)f[i].x=read();
REP(i,0,m-1)g[i].x=read();
times(f,g,n,m);
REP(i,0,n+m-1-1)printf("%d ",(int)(f[i].x+0.5));
puts("");
return 0;
}

NTT

#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=(a),_ed=(b);i<=_ed;++i)
#define DREP(i,a,b) for(int i=(a),_ed=(b);i>=_ed;--i)
typedef long long ll;
typedef unsigned long long ull;
inline int read(){
register int x=0,f=1;register char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
while(isdigit(ch)){x=x*10+(ch^'0');ch=getchar();}
return f?x:-x;
} const int N=(1<<18)+5,mod=998244353;
int n,k,f[N];char s[N];
inline int power(int b,int n){int ans=1;for(;n;n>>=1,b=1ll*b*b%mod)if(n&1)ans=1ll*ans*b%mod;return ans;}
inline void inc(int& x,int y){x=x+y<mod?x+y:x+y-mod;}
inline void dec(int& x,int y){x=x-y>=0?x-y:x-y+mod;} int trans[N],w[N];
void NTT(int* a,int n){
static ull f[N];
REP(i,0,n-1)f[i]=a[i];
REP(i,0,n-1)if(i<trans[i])swap(f[i],f[trans[i]]);
for(int len=2,d=1;len<=n;d=len,len<<=1)
for(int p=0;p<n;p+=len)
for(int i=p;i<p+d;++i){
int t=f[i+d]*w[d+i-p]%mod;
f[i+d]=f[i]+mod-t;f[i]+=t;
}
REP(i,0,n-1)a[i]=f[i]%mod;
}
void times(int* f,int* a,int m1,int m2,int lim){
static int g[N];
int n=1;for(;n<(m1+m2-1);n<<=1);
REP(i,0,n-1)trans[i]=(trans[i>>1]>>1)|(i&1?(n>>1):0);
for(int len=2,d=1;len<=n;d=len,len<<=1){
int e=power(3,(mod-1)/len);
REP(i,w[d]=1,d-1)w[d+i]=1ll*w[d+i-1]*e%mod;
}
REP(i,m1,n-1)f[i]=0;
REP(i,0,m2-1)g[i]=a[i];REP(i,m2,n-1)g[i]=0;
NTT(f,n);NTT(g,n);
REP(i,0,n-1)f[i]=1ll*f[i]*g[i]%mod;
NTT(f,n);int inv=power(n,mod-2);
reverse(f+1,f+n);
REP(i,0,lim-1)f[i]=1ll*f[i]*inv%mod;
REP(i,lim,n-1)f[i]=0;
} void inv(int* f,int m){
static int g[N],p[N];
int n=1;for(;n<m;n<<=1);
g[0]=power(f[0],mod-2);
for(int len=2;len<=n;len<<=1){
REP(i,0,(len>>1)-1)p[i]=g[i],g[i]=1ll*2*g[i]%mod;
times(p,p,len>>1,len>>1,len);times(p,f,len,len,len);
REP(i,0,len-1)inc(g[i],mod-p[i]);
}
REP(i,0,m-1)f[i]=g[i];
REP(i,0,n-1)g[i]=p[i]=0;
} void drv(int* f,int m){
REP(i,0,m-2)f[i]=1ll*(i+1)*f[i+1]%mod;
f[m-1]=0;
}
void itg(int* f,int m){
DREP(i,m-1,1)f[i]=1ll*power(i,mod-2)*f[i-1]%mod;
f[0]=0;
}
void ln(int* f,int m){
static int g[N];
REP(i,0,m-1)g[i]=f[i];
inv(f,m);drv(g,m);
times(f,g,m,m,m);
itg(f,m);
REP(i,0,m-1)g[i]=0;
} void exp(int* f,int m){
static int g[N],p[N];
int n=1;for(;n<m;n<<=1);
g[0]=1;
for(int len=2;len<=n;len<<=1){
REP(i,0,(len>>1)-1)p[i]=g[i];
ln(p,len);REP(i,0,len-1)p[i]=mod-p[i],inc(p[i],f[i]);
inc(p[0],1);
times(g,p,len>>1,len,len);
}
REP(i,0,m-1)f[i]=g[i];
REP(i,0,n-1)g[i]=p[i]=0;
} void spower(int* f,int m,int k){
ln(f,n);
REP(i,0,n-1)f[i]=1ll*k*f[i]%mod;
exp(f,n);
} void div(int* a,int* b,int m1,int m2,int* r){
static int f[N],g[N];
if(m1<m2){
REP(i,0,m1-1)r[i]=a[i];REP(i,m1,m2-1)r[i]=0;
return;
}
int lim=m1-m2+1;
REP(i,0,m1-1)f[i]=a[i];REP(i,0,m2-1)g[i]=b[i];
reverse(f,f+m1),reverse(g,g+m2);
REP(i,lim,m1-1)f[i]=0;REP(i,lim,m2-1)g[i]=0;
inv(g,lim);times(f,g,lim,lim,lim);
reverse(f,f+lim);
times(f,b,lim,m2,m1);
REP(i,0,m1-1)r[i]=a[i],dec(r[i],f[i]);
REP(i,0,m1-1)f[i]=0;REP(i,0,m2-1)g[i]=0;
} int main(){
//freopen("in.in","r",stdin);
n=read();scanf("%s",s);REP(i,0,strlen(s)-1)k=(1ll*k*10+(s[i]^'0'))%mod;
REP(i,0,n-1)f[i]=read();
spower(f,n,k);
REP(i,0,n-1)printf("%d%c",f[i],i==n-1?'\n':' ');
return 0;
}

FFT/NTT初探的更多相关文章

  1. FFT \ NTT总结(多项式的构造方法)

    前言.FFT  NTT 算法 网上有很多,这里不再赘述. 模板见我的代码库: FFT:戳我 NTT:戳我 正经向:FFT题目解题思路 \(FFT\)这个玩意不可能直接裸考的..... 其实一般\(FF ...

  2. [学习笔记&教程] 信号, 集合, 多项式, 以及各种卷积性变换 (FFT,NTT,FWT,FMT)

    目录 信号, 集合, 多项式, 以及卷积性变换 卷积 卷积性变换 傅里叶变换与信号 引入: 信号分析 变换的基础: 复数 傅里叶变换 离散傅里叶变换 FFT 与多项式 \(n\) 次单位复根 消去引理 ...

  3. FFT/NTT/MTT学习笔记

    FFT/NTT/MTT Tags:数学 作业部落 评论地址 前言 这是网上的优秀博客 并不建议初学者看我的博客,因为我也不是很了解FFT的具体原理 一.概述 两个多项式相乘,不用\(N^2\),通过\ ...

  4. FFT&NTT总结

    FFT&NTT总结 一些概念 \(DFT:\)离散傅里叶变换\(\rightarrow O(n^2)\)计算多项式卷积 \(FFT:\)快速傅里叶变换\(\rightarrow O(nlogn ...

  5. 快速构造FFT/NTT

    @(学习笔记)[FFT, NTT] 问题概述 给出两个次数为\(n\)的多项式\(A\)和\(B\), 要求在\(O(n \log n)\)内求出它们的卷积, 即对于结果\(C\)的每一项, 都有\[ ...

  6. FFT/NTT模板 既 HDU1402 A * B Problem Plus

    @(学习笔记)[FFT, NTT] Problem Description Calculate A * B. Input Each line will contain two integers A a ...

  7. FFT/NTT基础题总结

    在学各种数各种反演之前把以前做的$FFT$/$NTT$的题整理一遍 还请数论$dalao$口下留情 T1快速傅立叶之二 题目中要求求出 $c_k=\sum\limits_{i=k}^{n-1}a_i* ...

  8. $FFT/NTT/FWT$题单&简要题解

    打算写一个多项式总结. 虽然自己菜得太真实了. 好像四级标题太小了,下次写博客的时候再考虑一下. 模板 \(FFT\)模板 #include <iostream> #include < ...

  9. FFT&NTT数学解释

    FFT和NTT真是噩梦呢 既然被FFT和NTT坑够了,坑一下其他的人也未尝不可呢 前置知识 多项式基础知识 矩阵基础知识(之后会一直用矩阵表达) FFT:复数基础知识 NTT:模运算基础知识 单位根介 ...

随机推荐

  1. HTML入门(转义字符、行内样式和块级元素、定位、锚点、跑马灯标签、图片标签、表格标签的讲解)

    一.转义字符由特殊字符包裹的文本 会当做标签去解析 对应不换行空格 对应全角空格 em是字体排印学的计量单位,相当于当前指定的点数.其占据的宽度正好是1个中文宽度,而且基本上不受字体影响.<对应 ...

  2. nodejs环境使用Typeorm连接查询Oracle

    首先是typeorm的官方地址, 国内有人翻了中文版,不保证时效性 ·通过npm安装下列包: typeorm //typeorm连接数据库 @types/node //类型系统 typescript ...

  3. Linux系统学习 二十二、SAMBA服务—Samba基本使用—share权限访问、客户端的使用

    share权限访问 配置文件修改 [global]全局设置 workgroup=MYGROUP server string=Samba Server Lamp log file=/var/log/sa ...

  4. APScheduler学习

    说明 APScheduler是一个 Python 定时任务框架,使用起来十分方便.提供了基于日期.固定时间间隔以及 crontab 类型的任务,并且可以持久化任务.并以 daemon 方式运行应用. ...

  5. August 25th, 2019. Sunday, Week 35th.

    It's what you do next that counts, not what happens but what you decide to do about it. 重点不是发生了什么,而是 ...

  6. 06-Node.js学习笔记-创建web服务器

    创建web服务器 //引用系统模块 const http = require('http'); //创建web服务器 //用于处理url地址 const url = require('url'); c ...

  7. 搭建Harbor

    搭建Harbor 一.安装准备 二.安装docker-ce 三.安装docker-compose 四.安装harbor 5.1下载安装程序 5.2配置harbor.yml 5.3运行install.s ...

  8. 关于eclipse创建的[传统web项目][传统maven项目][maven-web项目][springboot项目]目录结构

    总体比较 [传统web项目] [传统maven项目] [maven-web项目] [springboot项目] 本文摘至https://blog.csdn.net/qq_42747738/articl ...

  9. PC端视频播放器

    视频播放器:Potplayer 它是一款纯净的.无广告.极速

  10. YAPI windows 二次开发 树形结构 多层级结构 拖拽 数据导入 接口自动化测试

    什么是YAPI: 高效.易用.功能强大的API管理平台 http://yapi.demo.qunar.com/ github: https://github.com/YMFE/yapi 可以去那里下载 ...