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

现在的一般来说任意模数求逆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. Python——Flask框架

    Flask框架相关知识构架 程序的基本结构 模板 Web表单 数据库 电子邮件 程序的结构 用户认证

  2. opencv 图片旋转

    import cv2 as cv import numpy as np # 图片旋转 img = cv.imread('../images/face.jpg', flags=1) # flags=1读 ...

  3. AHOI2019N省联考凉凉记

    博主并未时空穿越,本文没有对选手造成恐慌 DAY0 这已经是我第四次省选了,时间真快啊,怀念三年前毫无压力的省选,考完以后如果有时间并且没退役的话可能会陆续搬以前写在别处的游记(主要是2018年的游记 ...

  4. go interface接口

    一:接口概要 接口是一种重要的类型,他是一组确定的方法集合. 一个接口变量可以存储任何实现了接口方法的具体值.一个重要的例子就是io.Reader和io.Writer type Reader inte ...

  5. 为什么wait()方法要放在同步块

    回顾一下,如果wait()方法不在同步块中,代码的确会抛出异常: public class WaitInSyncBlockTest { @Test public void test() { try { ...

  6. 第一节:框架前期准备篇之Log4Net日志详解

    一. Log4Net简介 Log4net是从Java中的Log4j迁移过来的一个.Net版的开源日志框架,它的功能很强大,可以将日志分为不同的等级,以不同的格式输出到不同的存储介质中,比如:数据库.t ...

  7. django - 总结 - cnblog

    1.头像预览 -------方法1-------- 点击头像------>点击input img和input重合; img在label,input-->display:none $(&qu ...

  8. JavaScript事件的属性列表

    HTML 4.0 的新特性之一是能够使 HTML 事件触发浏览器中的行为,比如当用户点击某个 HTML 元素时启动一段 JavaScript.下面是一个属性列表,可将之插入 HTML 标签以定义事件的 ...

  9. babel

    一款可以将 ES6 代码转换为 ES5 代码的转译器. 官网:http://babeljs.io/ 中文:https://www.babeljs.cn/

  10. python学习第26天

    自定义模块和包 软件开发规范