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

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. Consul初探-集成ocelot

    前言 由于 Consul 的高可用性.丰富的API.友好的 Web 控制台界面等特点,Consul 的发展非常迅猛,得益于 .NETCore 社区的快速发展和社区成员的贡献,我们现在可以非常方便快速的 ...

  2. MySQL索引查询原理

    什么是索引? “索引”是为了能够更快地查询数据.比如一本书的目录,就是这本书的内容的索引,读者可以通过在目录中快速查找自己想要的内容,然后根据页码去找到具体的章节. 数据库也是一样,如果查询语句使用到 ...

  3. JS---DOM---元素创建的不同方式---三种方式,5个案例

    元素创建-----为了提高用户的体验   元素创建的三种方式: 1. document.write("标签的代码及内容"); 2. 对象.innerHTML="标签及代码 ...

  4. AWS云EC2(RHEL7)添加网络接口与路由调整

    AWS云EC2(RHEL7)添加网络接口与路由调整 Amazon Linux(类似RHEL6,Centos6) 以及 RHEL7 修改MAC地址的说明 RHEL7 Centos7 添加路由 解决RHE ...

  5. 005.SQLServer AlwaysOn可用性组高可用简介

    一 AlwaysOn 可用性组 1.1 AlwaysOn 可用性组概述 AlwaysOn 可用性组功能是一个提供替代数据库镜像的企业级方案的高可用性和灾难恢复解决方案.SQL Server 2012 ...

  6. Java Virtual Machine (JVM), Difference JDK, JRE & JVM – Core Java

    By Chaitanya Singh | Filed Under: Learn Java Java is a high level programming language. A program wr ...

  7. C# 请求在线接口数据

    请求后台,有很多方式,常见的有WebRequest.HttpClient.以下mark一上~ WebRequest方式 1. Get public static async Task<strin ...

  8. WPF TreeView 虚拟化-设置滚动到选中项

    前言 列表滚动到具体的数据项? ListBox提供了简易快捷的滚动定位函数ScrollIntoView. TreeView树状结构列表,则没有此类方法,无法与ListBox一样,直接设置滚动到具体的数 ...

  9. 你看不懂的spring原理是因为不知道这几个概念

    背景 问题从一杯咖啡开始. 今天我去楼下咖啡机买了一杯「粉黛拿铁」.制作过程中显示: 我取了做好的粉黛拿铁,喝了一口,果然就是一杯热巧克力.咦咦咦,说好的拿铁呢?虽然我对「零点吧」的咖啡评价很高,觉得 ...

  10. zookeeper启动失败,但是状态显示已启动的原因

    今天在起zookeeper集群的时候,其他两台机子都能起起来,只有这一台机子起不起来: 对比了 这个路径下的 文件后发现多了一个这个文件 根据名字推测应该是放进程id.突然明白这个应该是上次非正常退出 ...