三模NTT 不会。。。

都0202年了,还有人写三模NTT啊。。。


讲一个好写点的做法吧:

首先取一个阀值\(w\),然后把多项式的每个系数写成\(aw + c(c < w)\)的形式,换句话说把多项式\(f(x)\)写成两个多项式相加的形式:

\[f(x) = wf_0(x) + f_1(x)
\]

这样在这道题中取\(W = 2^{15}\)就可以避免爆long long了。

乘起来的话就是

\[f \cdot g = (w f_0 + f_1)(wg_0 + g_1) = (f_0 g_0)w^2 + (f_0g_1 + f_1g_0) w + f_1g_1
\]

这样我们只要算\(f_0g_0, (f_0g_1 + f_1g_0), f_1g_1\)就好了,分别\(FFT\)算一下。(这玩意儿好像叫\(MTT\),妙~啊)

这样要做\(7\)次\(FFT\),好像可以做到\(4\)次,不会。

感觉这样也跑的挺快的。

\(Code\)

#include <bits/stdc++.h>
using namespace std;
typedef long double db;
typedef long long ll;
const db PI=acos(-1.0);
const int N=3e5+10;
struct cpl{
db x,y;
cpl operator + (cpl k1)const{return (cpl){x+k1.x,y+k1.y};}
cpl operator - (cpl k1)const{return (cpl){x-k1.x,y-k1.y};}
cpl operator * (cpl k1)const{return (cpl){x*k1.x-y*k1.y,x*k1.y+y*k1.x};}
};
int rev[N];
void fft(cpl *f,int n,int k1){
for (int i=0;i<n;i++)
if (rev[i]<i)swap(f[i],f[rev[i]]);
for (int len=2;len<=n;len<<=1){
cpl wn=(cpl){cos(2*PI/len),k1*sin(2*PI/len)};
for (int i=0;i<n;i+=len){
cpl w=(cpl){1,0};
for (int j=i;j<i+(len>>1);j++){
cpl tmp=w*f[j+(len>>1)];
f[j+(len>>1)]=f[j]-tmp;
f[j]=f[j]+tmp;
w=w*wn;
}
}
}
}
cpl f[2][N],g[2][N],ans[3][N];
#define normal(x) (((ll)(x/limit+0.5)%mod+mod)%mod)
void mtt(int *a,int n,int *b,int m,int mod){
int limit=1; while (limit<=n+m)limit<<=1;
for (int i=0;i<limit;i++) rev[i]=rev[i>>1]>>1|((i&1)?limit>>1:0);
for (int i=0;i<limit;i++){
f[0][i].x=a[i]>>15;f[1][i].x=a[i]&0x7fff;
g[0][i].x=b[i]>>15;g[1][i].x=b[i]&0x7fff;
}
fft(f[0],limit,1),fft(f[1],limit,1);
fft(g[0],limit,1),fft(g[1],limit,1);
for (int i=0;i<limit;i++){
ans[0][i]=f[0][i]*g[0][i];
ans[1][i]=f[0][i]*g[1][i]+f[1][i]*g[0][i];
ans[2][i]=f[1][i]*g[1][i];
}
fft(ans[0],limit,-1),fft(ans[1],limit,-1),fft(ans[2],limit,-1);
for (int i=0;i<=n+m;i++){
ll k1=(normal(ans[0][i].x)<<30ll)%mod;
ll k2=(normal(ans[1][i].x)<<15ll)%mod;
ll k3=normal(ans[2][i].x)%mod;
printf("%d ",((k1+k2)%mod+k3)%mod);
}
}
int n,m,a[N],b[N],mod;
int main(){
scanf("%d%d%d",&n,&m,&mod);
for (int i=0;i<=n;i++)scanf("%d",&a[i]);
for (int i=0;i<=m;i++)scanf("%d",&b[i]);
mtt(a,n,b,m,mod);
return 0;
}

[题解] Luogu P4245 [模板]任意模数NTT的更多相关文章

  1. 洛谷 P4245 [模板]任意模数NTT —— 三模数NTT / 拆系数FFT(MTT)

    题目:https://www.luogu.org/problemnew/show/P4245 用三模数NTT做,需要注意时间和细节: 注意各种地方要取模!传入 upt() 里面的数一定要不超过2倍 m ...

  2. 洛谷.4245.[模板]任意模数NTT(MTT/三模数NTT)

    题目链接 三模数\(NTT\): 就是多模数\(NTT\)最后\(CRT\)一下...下面两篇讲的都挺明白的. https://blog.csdn.net/kscla/article/details/ ...

  3. [洛谷P4245]【模板】任意模数NTT

    题目大意:给你两个多项式$f(x)$和$g(x)$以及一个模数$p(p\leqslant10^9)$,求$f*g\pmod p$ 题解:任意模数$NTT$,最大的数为$p^2\times\max\{n ...

  4. 【模板】任意模数NTT

    题目描述: luogu 题解: 用$fft$水过(什么$ntt$我不知道). 众所周知,$fft$精度低,$ntt$处理范围小. 所以就有了任意模数ntt神奇$fft$! 意思是这样的.比如我要算$F ...

  5. MTT:任意模数NTT

    MTT:任意模数NTT 概述 有时我们用FFT处理的数据很大,而模数可以分解为\(a\cdot 2^k+1\)的形式.次数用FFT精度不够,用NTT又找不到足够大的模数,于是MTT就应运而生了. MT ...

  6. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  7. 任意模数NTT

    任意模数\(NTT\) 众所周知,为了满足单位根的性质,\(NTT\)需要质数模数,而且需要能写成\(a2^{k} + r\)且\(2^k \ge n\) 比较常用的有\(998244353,1004 ...

  8. BZOJ1042 HAOI2008硬币购物(任意模数NTT+多项式求逆+生成函数/容斥原理+动态规划)

    第一眼生成函数.四个等比数列形式的多项式相乘,可以化成四个分式.其中分母部分是固定的,可以多项式求逆预处理出来.而分子部分由于项数很少,询问时2^4算一下贡献就好了.这个思路比较直观.只是常数巨大,以 ...

  9. 【知识总结】多项式全家桶(三)(任意模数NTT)

    经过两个月的咕咕,"多项式全家桶" 系列终于迎来了第三期--(雾) 上一篇:[知识总结]多项式全家桶(二)(ln和exp) 先膜拜(伏地膜)大恐龙的博客:任意模数 NTT (在页面 ...

随机推荐

  1. 2017北京网络赛 J Pangu and Stones 区间DP(石子归并)

    #1636 : Pangu and Stones 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 In Chinese mythology, Pangu is the fi ...

  2. Ubuntu 16.04.4下安装apache服务

     Ubuntu 16.04.4下安装apache服务: 一.首先,准备需要的预装环境 需要c++,make,gcc,apr  apr-util  pcre.(如果后面报错缺少什么组件,可以百度搜方法. ...

  3. php hash算法实现memcached分布式

    一.概述Memcached和mysql一样,是一款客户端/服务器端(C/S)系统管理软件,有IP.端口,一旦启动,服务器就一直处于可用状态.Mysql是通过SQL语句管理“磁盘中”的文件,Memcac ...

  4. P1059 C语言竞赛

    P1059 C语言竞赛 转跳点:

  5. C++面试常见问题——12虚函数

    虚函数 虚函数的工作原理 虚函数的实现要求对象携带额外的信息,这些信息用于确定运行时调用哪一个虚函数,这一信息具有一种被称为虚函数表指针(vptr)的指针形式.vptr指向一个被称为虚函数表(vtbl ...

  6. bzoj 1138: [POI2009]Baj 最短回文路

    额,,貌似网上的题解都说超时之类的. 然而我这个辣鸡在做的时候不知道在想什么,连超时的都不会. 超时的大概是这样的,f[x][y]表示x到y的最短回文路,然后更新的话就是 f[x][y]更新到 f[a ...

  7. 序列号导出到csv的实现

    //导出到csv public function exportCsvByIds($ids){ header("Content-type:text/html;charset=utf-8&quo ...

  8. 习题两则的简化(利用for循环)

    习题一.打印26个英文字母 public class PrintChars { public static void main(String[] args) { char ch = 'a'; int ...

  9. 033.SAP上查看IDOC接口,PI接口查不到的日志记录,可能在IDOC接口日志里面

    01. SAP系统发料之后,数据没有传输到条码系统,同事也没有任何bc01的日志,这是就要考虑是不是在IDOC接口了,输入事务代码WE02或者WE05 02.双击查看内容 03.点开就能看到详细内容了 ...

  10. SQL计算字符串里的子字符串出现个数

    在某个页面,需要显示每条记录中有几个图片文件.图片文件名列表存储在mysql表里的photo_files字段,文件名之间用一个空格分开.类似'images\rpt201503121.jpg image ...