在被两题卡了常数之后,花了很久优化了自己的模板

现在的一般来说任意模数求逆1s跑3e5,exp跑1e5是没啥问题的(自己电脑,可能比luogu慢一倍)

当模数是$998244353,1004535809,9985661441$的时候(这$3$个的原根都是$3$)

我们会使用$ntt$来求解

$ntt$的模板本身常数不大 优化效果不明显

const int mo=;
const int G=;
IL int fsp(int x,int y)
{
ll now=;
while (y)
{
if (y&) now=now*x%mo;
x=1ll*x*x%mo;
y>>=;
}
return now;
}
IL void ntt_init()
{
l=; for (n=;n<=m;n<<=) l++;
for (int i=;i<n;i++) r[i]=(r[i/]/)|((i&)<<(l-));
}
IL void clear()
{
for (int i=;i<=n;i++) a[i]=b[i]=;
}
void ntt(int *a,int o)
{
for (int i=;i<n;i++) if (i>r[i]) swap(a[i],a[r[i]]);
for (int i=;i<n;i<<=)
{
int wn=fsp(G,(mo-)/(i*)); w[]=;
rep(j,,i-) w[j]=(1ll*w[j-]*wn)%mo;
for (int j=;j<n;j+=(i*))
for (int k=;k<i;k++)
{
int x=a[j+k],y=1ll*a[i+j+k]*w[k]%mo;
a[j+k]=(x+y)%mo; a[i+j+k]=(x-y)%mo;
}
}
if (o==-)
{
reverse(&a[],&a[n]);
for (int i=,inv=fsp(n,mo-);i<n;i++)
a[i]=1ll*a[i]*inv%mo;
}
}
IL void getcj(int *A,int *B,int len)
{
m=len*2; ntt_init();
for (int i=0;i<len;i++) a[i]=A[i],b[i]=B[i];
ntt(a,1); ntt(b,1);
for(int i=0;i<n;i++) a[i]=1ll*a[i]*b[i]%mo;
ntt(a,-1);
for (int i=0;i<len;i++) B[i]=a[i];
clear();
}
 

当模数不为这$3$个,我们就需要$mtt$来实现

而$mtt$的实现为用$mx$的方法将数的实部虚部分别放$x \& 65536,x(>>15)$

另外一个重要的地方是要预处理出$w$,我们采用指针来存,避免使用vector

代码$p$的初始值为$2*n$

所有数组大小为$4*n$

$getcj$的时候要先把数组中的负数变正

IL void clear()
{
for (int i=;i<=n;i++) a[i].a=a[i].b=b[i].a=b[i].b=c[i].a=c[i].b=d[i].a=d[i].b=;
}
cp *w[N],tmp[N*];
int p;
IL void init()
{
cp *now=tmp;
for (int i=;i<=p;i<<=)
{
w[i]=now;
for (int j=;j<i;j++) w[i][j]=(cp){cos(pi*j/i),sin(pi*j/i)};
now+=i;
}
}
IL void fft_init()
{
l=; for (n=;n<=m;n<<=) l++;
for (int i=;i<n;i++) r[i]=(r[i/]/)|((i&)<<(l-));
}
void fft(cp *a,int o)
{
for (int i=;i<n;i++) if (i>r[i]) swap(a[i],a[r[i]]);
for (int i=;i<n;i<<=)
for (int j=;j<n;j+=(i*))
{
cp *x1=a+j,*x2=a+i+j,*W=w[i];
for (int k=;k<i;k++,x1++,x2++,W++)
{
cp x=*x1,y=(cp){(*W).a,(*W).b*o}*(*x2);
*x1=x+y,*x2=x-y;
}
}
if (o==-) for(int i=;i<n;i++) a[i].a/=n;
}
IL void getcj(int *A,int *B,int len)
{
rep(i,,len)
{
A[i]=(A[i]+mo)%mo,B[i]=(B[i]+mo)%mo;
}
for (int i=;i<len;i++)
{
a[i]=(cp){A[i]&,A[i]>>};
b[i]=(cp){B[i]&,B[i]>>};
}
m=len*; fft_init();
fft(a,); fft(b,);
for (int i=;i<n;i++)
{
int j=(n-)&(n-i);
c[j]=(cp){0.5*(a[i].a+a[j].a),0.5*(a[i].b-a[j].b)}*b[i];
d[j]=(cp){0.5*(a[i].b+a[j].b),0.5*(a[j].a-a[i].a)}*b[i];
}
fft(c,); fft(d,);
double inv=ee/n;
rep(i,,n) c[i].a*=inv,c[i].b*=inv;
rep(i,,n) d[i].a*=inv,d[i].b*=inv;
rep(i,,len)
{
ll a1=c[i].a+0.5,a2=c[i].b+0.5;
ll a3=d[i].a+0.5,a4=d[i].b+0.5;
B[i]=(a1+((a2+a3)%mo<<)+((a4%mo)<<))%mo;
}
clear();
}

对于其他的多项式函数

用$fft$还是$ntt$是差不多的(除了数组类型)

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:模运算基础知识 单位根介 ...

  10. HDU-4609(FFT/NTT)

    HDU-4609(FFT/NTT) 题意: 给出n个木棒,现从中不重复地选出3根来,求能拼出三角形的概率. 计算合法概率容易出现重复,所以建议计算不合法方案数 枚举选出的最大边是哪条,然后考虑剩下两条 ...

随机推荐

  1. [模板] 平衡树: Splay, 非旋Treap, 替罪羊树

    简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...

  2. 皮尔逊相关系数与余弦相似度(Pearson Correlation Coefficient & Cosine Similarity)

    之前<皮尔逊相关系数(Pearson Correlation Coefficient, Pearson's r)>一文介绍了皮尔逊相关系数.那么,皮尔逊相关系数(Pearson Corre ...

  3. 【CQOI2017】【BZOJ4813】小Q的棋盘 DFS

    题目描述 有一棵树,你要从\(0\)号点开始走,你可以走\(m\)步,问你最多能经过多少个不同的点. \(n\leq 100\) 题解 出题人的做法是DP(一个简单的树形DP),但是可以直接通过一次D ...

  4. Linux systemctl 命令完全指南

    Systemctl是一个systemd工具,主要负责控制systemd系统和服务管理器. Systemd是一个系统管理守护进程.工具和库的集合,用于取代System V初始进程.Systemd的功能是 ...

  5. Spring中的AOP 专题

    Caused by: java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advi ...

  6. 基于前后端分离的身份认证方式——JWT

    什么是JWT JWT--Json web token 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,可实现无状态.分布式的Web应用授权. 现在一般都用redis来出来token做 ...

  7. 计算机基础理论知识梳理篇(一):数据类型长度、内存页、IPC

    字长与数据类型长度 字长指CPU在同一时间能够处理二进制数据的位数,是由其外接数据总线(地址总线决定了CPU的寻址空间,如16位微型机的地址总线为20位,其可寻址空间为220 = 1MB)的条数决定的 ...

  8. centos7搭建gitlab服务器、汉化

    1.下载rpm安装包 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-8.8.5-ce.1.el7.x86_64.rp ...

  9. redis简单命令总结

    1.连接到redis服务器:redis-cli -h 127.0.0.1 -p 6379 -a 密码 select index 切换 redis 数据库 flushdb 删除当前数据库所有的 key ...

  10. C# 操作SQL Server 公共库

    基本够用,存一下,以后找起来方便 public abstract class DB { //数据库连接字符串(config来配置) protected static string connection ...