正题

题目链接:https://www.luogu.com.cn/problem/P4245


题目大意

两个多项式,求它们的乘积模\(p\)。


解题思路

方法好像挺多,我用的是最简单的一种就是,先定一个常数\(sqq\)(一般是\(\sqrt q\)),把一个项的数\(x\)拆成\(k*sqq+r\)。然后把\(F\)的\(k\)丢进\(A\),\(r\)丢进\(B\)。\(G\)的\(k\)丢进\(C\),\(r\)丢进\(D\)。

然后对于\(A*C\)的部分就是\(sqq^2\)的部分,\(A*D+B*C\)就是\(sqq\),\(C*D\)就是\(1\)。这样下来要跑\(7\)次\(\text{FFT}\),很慢但是能过,而且要开\(\text{long double}\)和预处理单位根不然会被卡精度。

有一个比较快的方法是变成两个复数多项式\(E[x]=A[x]+B[x]*i,F[x]=C[x]+D[x]*i\)(其中\(i\)表示\(\sqrt{-1}\))。然后乘起来做一下公式就可以做到\(3\)次\(\text{FFT}\)。

还有一个就是不会被卡精度的\(\text{NTT}\)方法,就是找三个有原根的模数分别跑出来,然后用\(\text{CRT}\)合并,这个跑的次数多,但是因为是\(\text{NTT}\)所以常数和第一个差不多?

时间复杂度都是\(O(n\log n)\)就是常数有不同而已


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const ll N=4e5+10,sqq=32768;
const long double Pi=acos(-1);
struct complex{
long double x,y;
complex (long double xx=0,long double yy=0)
{x=xx;y=yy;return;}
}A[N],B[N],C[N],D[N];
complex operator+(complex a,complex b)
{return complex(a.x+b.x,a.y+b.y);}
complex operator-(complex a,complex b)
{return complex(a.x-b.x,a.y-b.y);}
complex operator*(complex a,complex b)
{return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
ll n,m,p,F[N],G[N],H[N],r[N];
complex w[N];
void FFT(complex *f,ll op,ll n){
for(ll i=0;i<n;i++)
if(i<r[i])swap(f[i],f[r[i]]);
for(ll p=2;p<=n;p<<=1){
ll len=p>>1;
for(ll k=0;k<n;k+=p)
for(ll i=k;i<k+len;i++){
complex tmp=w[n/len*(i-k)];
if(op==-1)tmp.y=-tmp.y;
complex tt=f[i+len]*tmp;
f[i+len]=f[i]-tt;
f[i]=f[i]+tt;
}
}
if(op==-1){
for(ll i=0;i<n;i++)
f[i].x=(ll)(f[i].x/n+0.49);
}
return;
}
void MTT(ll *a,ll *b,ll *c,ll m,ll k){
ll n=1;
while(n<=m+k)n<<=1;
for(ll i=0;i<n;i++)
r[i]=(r[i>>1]>>1)|((i&1)?(n>>1):0);
for(ll len=1;len<n;len<<=1)
for(ll i=0;i<len;i++)
w[n/len*i]=complex(cos(i*Pi/len),sin(i*Pi/len));
for(ll i=0;i<m;i++)
A[i].x=a[i]/sqq,B[i].x=a[i]%sqq;
for(ll i=0;i<k;i++)
C[i].x=b[i]/sqq,D[i].x=b[i]%sqq;
FFT(A,1,n);FFT(B,1,n);FFT(C,1,n);FFT(D,1,n);
complex t1,t2;
for(ll i=0;i<n;i++){
t1=A[i]*C[i];t2=B[i]*D[i];
B[i]=A[i]*D[i]+B[i]*C[i];
A[i]=t1;C[i]=t2;
}
FFT(A,-1,n);FFT(B,-1,n);FFT(C,-1,n);
for(ll i=0;i<n;i++){
(c[i]+=(ll)(A[i].x)*sqq%p*sqq%p)%=p;
(c[i]+=(ll)(B[i].x)*sqq%p)%=p;
(c[i]+=(ll)(C[i].x))%=p;
}
return;
}
signed main()
{
scanf("%lld%lld%lld",&n,&m,&p);
n++;m++;
for(ll i=0;i<n;i++)scanf("%lld",&F[i]);
for(ll i=0;i<m;i++)scanf("%lld",&G[i]);
MTT(F,G,H,n,m);
for(ll i=0;i<n+m-1;i++)
printf("%lld ",(H[i]%p+p)%p);
}

P4245-[模板]任意模数多项式乘法的更多相关文章

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

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

  2. [题解] Luogu P4245 [模板]任意模数NTT

    三模NTT 不会... 都0202年了,还有人写三模NTT啊... 讲一个好写点的做法吧: 首先取一个阀值\(w\),然后把多项式的每个系数写成\(aw + c(c < w)\)的形式,换句话说 ...

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

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

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

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

  5. FFT/NTT总结+洛谷P3803 【模板】多项式乘法(FFT)(FFT/NTT)

    前言 众所周知,这两个东西都是用来算多项式乘法的. 对于这种常人思维难以理解的东西,就少些理解,多背板子吧! 因此只总结一下思路和代码,什么概念和推式子就靠巨佬们吧 推荐自为风月马前卒巨佬的概念和定理 ...

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

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

  7. 51NOD 1258 序列求和 V4 [任意模数fft 多项式求逆元 伯努利数]

    1258 序列求和 V4 题意:求\(S_m(n) = \sum_{i=1}^n i^m \mod 10^9+7\),多组数据,\(T \le 500, n \le 10^{18}, k \le 50 ...

  8. FFT模板(多项式乘法)

    FFT模板(多项式乘法) 标签: FFT 扯淡 一晚上都用来捣鼓这个东西了...... 这里贴一位神犇的博客,我认为讲的比较清楚了.(刚好适合我这种复数都没学的) http://blog.csdn.n ...

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

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

随机推荐

  1. java获取真实ip工具类

    场景 有的时候我们需要获取客户端的真实ip,用来实现ip白名单,和黑名单的配置! ip工具类如下 package com.meeno.framework.utils; import javax.ser ...

  2. C语言预处理编译链接各个阶段错误,分阶段的说一下

    C语言预处理编译链接各个阶段错误,分阶段的说一下 C语言预处理编译链接各个阶段错误,分阶段的说一下比如指针异常,数组下标越界什么的    我来答 1个回答 #热议# 你觉得这辈子有希望看到996消失 ...

  3. C#串口通信SeriPort 电表DLT645 RS234/RS485

    难受,三个多月前有一个电表电量监控的项目.做完了就没再管了.今天有需求需要改一些地方,但是....我想不起来干了啥,怎么干的啦.真的完全忘了.....项目名称叫啥都忘了.找了半天 不知道有没有和我一样 ...

  4. 辗转相除 求最大公约数!or 最小公倍数

    求最大公约数和最小公倍数的经典算法--辗转相除法描述如下: 若要求a,b两数的最大公约数和最小公倍数,令a为a.b中较大数,b为较小数,算法进一步流程: while(b不为0) { temp=a%b: ...

  5. 读vue-cli3 官方文档的一些学习记录

    原来一直以为vue@cli3 就是创建模板的工具,读了官方文档才知道原来这么有用,不少配置让我长见识了 Prefetch 懒加载配置 懒加载相信大家都是知道的,使用Import() 语法就可以在需要的 ...

  6. Go版本管理--依赖包存储

    目录 1. 简介 2. GOPATH 依赖包存储 3.GOMODULE 依赖包存储 4.包名大小写敏感问题 1. 简介 GOPATH模式下,依赖包存储在$GOPATH/src,该目录下只保存特定依赖包 ...

  7. win系统打不开CHM文件(例如JDK的API)

    打开文件乱码,打开时弹出乱码 前提说明,存放路径不得有中文,文件名也不能有中文 检查下面三个文件:    hh.exe文件放置电脑 C:\Windows目录下:     hhctrl.ocx ,its ...

  8. Docker编排工具Docker Compose的使用

    一.安装docker compose 官网推荐方式之一: sudo curl -L "https://github.com/docker/compose/releases/download/ ...

  9. Linux从头学12:读完这篇【特权级】文章,你就比别人更“精通”操作系统!

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  10. ansible 批量安装yum包

    1.首先安装一下ansible yum install ansible 2.修改一下ansible的参数以防ssh过去的时候需要首次判断yes  或者no sed -i 's/#host_key_ch ...