思路

多项式除法板子

多项式除法

给出\(A(x)\)和\(B(x)\),求一个\(n-m\)次的多项式\(D(x)\),一个\(m-1\)次多项式\(R(x)\),满足

\[A(x)=B(x)D(x)+R(x)
\]

定义\(D^R(x)\)为多项式\(D(x)\)系数反转的结果,可证\(D^R(x)=x^nD(\frac{1}{x})\)

所以

\[\begin{align}&A(x)=B(x)D(x)+R(x)\\&A(\frac{1}{x})=B(\frac{1}{x})D(\frac{1}{x})+R(\frac{1}{x})\\&x^nA(\frac{1}{x})=x^nB(\frac{1}{x})D(\frac{1}{x})+x^nR(\frac{1}{x})\\&A^R(x)=B^R(x)D^R(x)+x^{n-m+1}R^R(x)\end{align}
\]

放到模\(x^{n-m+1}\)意义下

就消去了\(R(x)\)的影响,然后上求逆就行了

注意反转D系数时候只反转0~n-m项系数

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int MAXN = 300000;
const int G = 3;
const int invG = 332748118;
const int MOD = 998244353;
int n,m;
struct Poly{
int t;//次数界
int data[MAXN];
Poly(){}
Poly(int x,int val[]){
for(int i=0;i<=x;i++)
data[i]=val[i];
}
};
int pow(int a,int b){
int ans=1;
while(b){
if(b&1)
ans=(1LL*ans*a)%MOD;
a=(1LL*a*a)%MOD;
b>>=1;
}
return ans;
}
void rever(Poly &a){
for(int i=0,j=a.t;i<j;i++,j--){
swap(a.data[i],a.data[j]);
}
}
void save(Poly &a,int top){
for(int i=top+1;i<=a.t;i++)
a.data[i]=0;
a.t=top;
}
void output(Poly a){
putchar('\n');
printf("a.times=%lld\n",a.t);
putchar('\n');
for(int i=0;i<=a.t;i++)
printf("%lld ",a.data[i]);
putchar('\n');
putchar('\n');
}
void NTT(Poly &a,int opt,int n){//1 DFT 0 IDFT
int lim=0;
while((1<<(lim))<n)
lim++;
n=(1<<lim);
for(int i=0;i<n;i++){
int t=0;
for(int j=0;j<lim;j++)
if((i>>j)&1)
t|=(1<<(lim-j-1));
if(i<t)
swap(a.data[i],a.data[t]);
}
for(int i=2;i<=n;i<<=1){
int len=i/2;
int tmp=pow((opt)?G:invG,(MOD-1)/i);
for(int j=0;j<n;j+=i){
int arr=1;
for(int k=j;k<j+len;k++){
int t=(1LL*a.data[k+len]*arr)%MOD;
a.data[k+len]=(a.data[k]-t+MOD)%MOD;
a.data[k]=(a.data[k]+t)%MOD;
arr=(1LL*arr*tmp)%MOD;
}
}
}
if(!opt){
int invN = pow(n,MOD-2);
for(int i=0;i<n;i++){
a.data[i]=(a.data[i]*invN)%MOD;
}
}
}
void mul(Poly &a,Poly b){//a=a*b
int num=(a.t+b.t),lim=0;
while((1<<(lim))<=((num+2)))
lim++;
lim=(1<<lim);
NTT(a,1,lim);
NTT(b,1,lim);
for(int i=0;i<lim;i++)
a.data[i]=(1LL*a.data[i]*b.data[i])%MOD;
NTT(a,0,lim);
a.t=num;
for(int i=num+1;i<lim;i++)
a.data[i]=0;
}
void Inv(Poly a,Poly &inv,int dep,int &len){//
if(dep==1){
inv.data[0]=pow(a.data[0],MOD-2);
inv.t=dep-1;
return;
}
Inv(a,inv,(dep+1)>>1,len);
static Poly tmp;
while((dep<<1)>len)
len<<=1;
for(int i=0;i<dep;i++)
tmp.data[i]=a.data[i];
for(int i=dep;i<len;i++)
tmp.data[i]=0;
NTT(tmp,1,len);
NTT(inv,1,len);
for(int i=0;i<len;i++)
inv.data[i]=1LL*inv.data[i]*((2-1LL*inv.data[i]*tmp.data[i])%MOD+MOD)%MOD;
NTT(inv,0,len);
for(int i=dep;i<len;i++)
inv.data[i]=0;
inv.t=dep-1;
}
void div(Poly a,Poly b,Poly &D,Poly &R){
static Poly tmp1,tmp2;
int Up=a.t-b.t+1,midlen=1;
tmp1=b;
rever(tmp1);
Inv(tmp1,tmp2,Up,midlen);
tmp1=a;
rever(tmp1);
mul(tmp2,tmp1);
save(tmp2,n-m);
rever(tmp2);
D=tmp2;
mul(tmp2,b);
for(int i=0;i<b.t;i++)
R.data[i]=(a.data[i]-tmp2.data[i]+MOD)%MOD;
R.t=b.t-1;
}
Poly a,b,D,R;
signed main(){
scanf("%lld %lld",&n,&m);
for(int i=0;i<=n;i++)scanf("%lld",&a.data[i]);
a.t=n;
for(int i=0;i<=m;i++)
scanf("%lld",&b.data[i]);
b.t=m;
div(a,b,D,R);
for(int i=0;i<=D.t;i++)
printf("%lld ",D.data[i]);
putchar('\n');
for(int i=0;i<=R.t;i++)
printf("%lld ",R.data[i]);
putchar('\n');
return 0;
}

P4512 【模板】多项式除法的更多相关文章

  1. 洛谷 P4512 [模板] 多项式除法

    题目:https://www.luogu.org/problemnew/show/P4512 看博客:https://www.cnblogs.com/owenyu/p/6724611.html htt ...

  2. 洛谷.4512.[模板]多项式除法(NTT)

    题目链接 多项式除法 & 取模 很神奇,记录一下. 只是主要部分,更详细的和其它内容看这吧. 给定一个\(n\)次多项式\(A(x)\)和\(m\)次多项式\(D(x)\),求\(deg(Q) ...

  3. [洛谷P4512]【模板】多项式除法

    题目大意:给定一个$n$次多项式$F(x)$和一个$m$次多项式$G(x)$,请求出多项式$Q(x),R(x)$,满足: 1. $Q(x)$次数为$n-m$,$R(x)$次数小于$m$2. $F(x) ...

  4. Re.多项式除法/取模

    前言 emmm又是暂无 前置 多项式求逆 多项式除法/取模目的 还是跟之前一样顾名思义] 给定一个多项式F(x),请求出多项式Q(x)和R(x),满足F(x)=Q(x)∗G(x)+R(x),R项数小于 ...

  5. xdoj-1211 (尧老师要教孩子解方程) :多项式除法

    想法: 1 由于所有a[i] 是不为0的整数 所以解x是整数 2 其次解是an的约数 3 分解a[n] 用多项式除法判断约数是否为整式的解 #include<cstdio> #includ ...

  6. 【Codechef】Random Number Generator(多项式除法)

    题解 前置技能 1.多项式求逆 求\(f(x)\*g(x) \equiv 1 \pmod {x^{t}}\) 我们在t == 1时,有\(f[0] = frac{1}{g[0]}\) 之后呢,我们倍增 ...

  7. luogu P4512 多项式除法 (模板题、FFT、多项式求逆)

    手动博客搬家: 本文发表于20181206 14:42:53, 原地址https://blog.csdn.net/suncongbo/article/details/84853342 题目链接: ht ...

  8. 题解 P4512 【【模板】多项式除法】

    题目地址 前言 原理有大佬写了 所以蒟蒻只讲下本题的代码细节 我看懂的大佬博客:博客地址 因为可能知道了大致的步骤还有很多细的地方不理解导致写的时候要花很久并且看到大佬们好像都是用递归写的希望能有帮助 ...

  9. 2019.01.02 洛谷P4512 【模板】多项式除法

    传送门 解析 代码: #include<bits/stdc++.h> #define ri register int using namespace std; typedef long l ...

随机推荐

  1. Linux上传文件与执行

    ls ——查看文件夹 mkdir——新建文件夹 cd:——进入文件 nohup python3 文件名.py & ——让代码在后台运行 ps -aux | grep 文件——查看进程 ps-a ...

  2. 使用docker容器运行MySQL数据库并持久化数据文件

    1.下载mysql镜像 # docker pull mysql 2.启动mysql容器 # docker run -itd -v /data:/var/lib/mysql -p 33060:3306 ...

  3. python-----函数参数类型

    #函数参数类型:1 位置参数 2 默认参数 3 关键字参数 4可变参数 包裹位置参数*args 包裹关键字参数 **kargs#参数位置顺序:先位置参数,默认参数,包裹位置,包裹关键字(定义和调用都应 ...

  4. Linux是cat、tail、head查看文件任意几行的数据

    Linux是cat.tail.head查看文件任意几行的数据 一.使用cat.tail.head组合 1.查看最后100行的数据 cat filename | tail -n 100 2.查看100到 ...

  5. jdbc--取大量数据

    最近使用jdbc方式查询数据,保存为csv文件中.当然你可以在pl/sql中直接查出来,copy to excel就好了.但我想通过程序实现 @Test public void test() thro ...

  6. C#基础加强(2)之密闭类、静态类及扩展方法

    密闭类 简介 密闭类是被 sealed 关键字修饰的类,密闭类不能有子类.一般只有系统的一些基本类声明为密闭类,例如 String 类. 相关面试题 是否可以编写一个类继承自 String 类? 我们 ...

  7. linux-grep-tail-find

    如果在只是想匹配模式的上下几行,grep可以实现. $grep -5 'parttern' inputfile //打印匹配行的前后5行 $grep -C 5 'parttern' inputfile ...

  8. 【二次开发】shopxo商城

    https://shopxo.net/ [问题1:配置邮箱注册]https://ask.shopxo.net/article/19

  9. shiro学习总结

    首先4个比较好的例子供参考: 1.常规Spring MVC拦截器实现的认证和权限管理例子 https://blog.csdn.net/u013647382/article/details/539956 ...

  10. SPP空间金字塔池化技术的直观理解

    空间金字塔池化技术, 厉害之处,在于使得我们构建的网络,可以输入任意大小的图片,不需要经过裁剪缩放等操作. 是后续许多金字塔技术(psp,aspp等)的起源,主要的目的都是为了获取场景语境信息,获取上 ...