luoguP4512 【模板】多项式除法 NTT+多项式求逆+多项式除法
// luogu-judger-enable-o2
#include <cstdio>
#include <string>
#include <algorithm>
#include <cstring>
#include <vector>
#define setIO(s) freopen(s".in","r",stdin)
typedef long long ll;
const int maxn=2100005;
const ll mod=998244353;
using namespace std;
inline ll qpow(ll base,ll k) {
ll tmp=1;
for(;k;k>>=1,base=base*base%mod)if(k&1) tmp=tmp*base%mod;
return tmp;
}
inline ll inv(ll a) { return qpow(a, mod-2); }
inline void NTT(ll *a,int len,int flag) {
for(int i=0,k=0;i<len;++i) {
if(i>k) swap(a[i],a[k]);
for(int j=len>>1;(k^=j)<j;j>>=1);
}
for(int mid=1;mid<len;mid<<=1) {
ll wn=qpow(3, (mod-1)/(mid<<1)),x,y;
if(flag==-1) wn=qpow(wn,mod-2);
for(int i=0;i<len;i+=(mid<<1)) {
ll w=1;
for(int j=0;j<mid;++j) {
x=a[i+j],y=w*a[i+j+mid]%mod;
a[i+j]=(x+y)%mod, a[i+j+mid]=(x-y+mod)%mod;
w=w*wn%mod;
}
}
}
if(flag==-1) {
int re=qpow(len,mod-2);
for(int i=0;i<len;++i) a[i]=a[i]*re%mod;
}
}
ll A[maxn],B[maxn];
struct poly {
vector<ll>a;
int len;
poly(){}
inline void clear() { len=0; a.clear(); }
inline void rev() {reverse(a.begin(), a.end()); }
inline void push(int x) { a.push_back(x),++len; }
inline void resize(int x) { len=x; a.resize(x); }
void getinv(poly &b,int n) {
if(n==1) { b.clear(); b.push(inv(a[0])); return; }
getinv(b,n>>1);
int t=n<<1,lim=min(len,n);
for(int i=0;i<lim;++i) A[i]=a[i];
for(int i=lim;i<t;++i) A[i]=0;
for(int i=0;i<b.len;++i) B[i]=b.a[i];
for(int i=b.len;i<t;++i) B[i]=0;
NTT(A,t,1),NTT(B,t,1);
for(int i=0;i<t;++i) A[i]=(2-A[i]*B[i]%mod+mod)*B[i]%mod;
NTT(A,t,-1);
b.clear();
for(int i=0;i<n;++i) b.push(A[i]);
}
poly Inv() {
int n=1;
while(n<=len)n<<=1;
poly b;
b.clear(), getinv(b,n);
return b;
}
poly operator * (const poly &b) const {
int n=1;
while(n<=len+b.len) n<<=1;
for(int i=0;i<len;++i) A[i]=a[i];
for(int i=len;i<n;++i) A[i]=0;
for(int i=0;i<b.len;++i) B[i]=b.a[i];
for(int i=b.len;i<n;++i) B[i]=0;
NTT(A,n,1), NTT(B,n,1);
for(int i=0;i<n;++i) A[i]=A[i]*B[i]%mod;
NTT(A,n,-1);
poly c;
c.clear();
for(int i=0;i<len+b.len-1;++i) c.push(A[i]);
return c;
}
poly operator + (const poly &b) const {
poly c;
c.clear();
for(int i=0;i<len;++i) c.push(a[i]);
for(int i=0;i<b.len;++i) {
if(i<len) c.a[i]=(c.a[i]+b.a[i])%mod;
else c.push(b.a[i]);
}
return c;
}
poly operator - (const poly &b) const {
poly c;
c.clear();
for(int i=0;i<len;++i) c.push(a[i]);
for(int i=0;i<b.len;++i) {
if(i<len) c.a[i]=(c.a[i]-b.a[i]+mod)%mod;
else c.push((mod-b.a[i])%mod);
}
return c;
}
friend poly operator / (poly f,poly g) {
poly Q;
int l=f.len-g.len+1;
f.rev(), g.rev(), g.resize(l), f.resize(l);
g=g.Inv(), Q=f*g, Q.resize(l),Q.rev();
return Q;
}
friend poly operator % (poly f,poly g) {
poly u=f-(f/g)*g;
u.resize(g.len-1);
return u;
}
}po[4];
inline void inv() {
int n,x;
scanf("%d",&n), po[0].clear();
for(int i=0;i<n;++i) scanf("%d",&x), po[0].push(x);
po[1]=po[0].Inv();
for(int i=0;i<po[1].len;++i) printf("%lld ",po[1].a[i]);
}
inline void mult() {
int n,m,x;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;++i) scanf("%d",&x), po[0].push(x);
for(int i=0;i<=m;++i) scanf("%d",&x), po[1].push(x);
po[1]=po[0]*po[1];
for(int i=0;i<po[1].len;++i) printf("%lld ",po[1].a[i]);
}
inline void divide() {
int n,m,x;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;++i) scanf("%d",&x), po[0].push(x);
for(int i=0;i<=m;++i) scanf("%d",&x), po[1].push(x);
po[2]=po[0]/po[1];
for(int i=0;i<po[2].len;++i) printf("%lld ",po[2].a[i]);
printf("\n");
po[2]=po[0]%po[1];
for(int i=0;i<po[2].len;++i) printf("%lld ",po[2].a[i]);
}
int main() {
// setIO("input");
divide();
return 0;
}
luoguP4512 【模板】多项式除法 NTT+多项式求逆+多项式除法的更多相关文章
- FFT模板 生成函数 原根 多项式求逆 多项式开根
FFT #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> ...
- BZOJ 3625 [Codeforces Round #250]小朋友和二叉树 ——NTT 多项式求逆 多项式开根
生成函数又有奇妙的性质. $F(x)=C(x)*F(x)*F(x)+1$ 然后大力解方程,得到一个带根号的式子. 多项式开根有解只与常数项有关. 发现两个解只有一个是成立的. 然后多项式开根.求逆. ...
- 牛顿迭代,多项式求逆,除法,开方,exp,ln,求幂
牛顿迭代 若 \[G(F_0(x))\equiv 0(mod\ x^{2^t})\] 牛顿迭代 \[F(x)\equiv F_0(x)-\frac{G(F_0(x))}{G'(F_0(x))}(mod ...
- [模板]多项式全家桶小记(求逆,开根,ln,exp)
前言 这里的全家桶目前只包括了\(ln,exp,sqrt\).还有一些类似于带余数模,快速幂之类用的比较少的有时间再更,\(NTT\)这种前置知识这里不多说. 还有一些基本的导数和微积分内容要了解,建 ...
- NTT+多项式求逆+多项式开方(BZOJ3625)
定义多项式$h(x)$的每一项系数$h_i$,为i在c[1]~c[n]中的出现次数. 定义多项式$f(x)$的每一项系数$f_i$,为权值为i的方案数. 通过简单的分析我们可以发现:$f(x)=\fr ...
- 【BZOJ3456】轩辕朗的城市规划 无向连通图计数 CDQ分治 FFT 多项式求逆 多项式ln
题解 分治FFT 设\(f_i\)为\(i\)个点组成的无向图个数,\(g_i\)为\(i\)个点组成的无向连通图个数 经过简单的推导(枚举\(1\)所在的连通块大小),有: \[ f_i=2^{\f ...
- 2019.01.01 bzoj3625:小朋友和二叉树(生成函数+多项式求逆+多项式开方)
传送门 codeforces传送门codeforces传送门codeforces传送门 生成函数好题. 卡场差评至今未过 题意简述:nnn个点的二叉树,每个点的权值KaTeX parse error: ...
- 【BZOJ3625】【codeforces438E】小朋友和二叉树 生成函数+多项式求逆+多项式开根
首先,我们构造一个函数$G(x)$,若存在$k∈C$,则$[x^k]G(x)=1$. 不妨设$F(x)$为最终答案的生成函数,则$[x^n]F(x)$即为权值为$n$的神犇二叉树个数. 不难推导出,$ ...
- bzoj 3456 城市规划——分治FFT / 多项式求逆 / 多项式求ln
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3456 分治FFT: 设 dp[ i ] 表示 i 个点时连通的方案数. 考虑算补集:连通的方 ...
随机推荐
- 洛谷P1466 集合 Subset Sums_01背包水题
不多解释,适当刷刷水… Code: #include<cstdio> #include<algorithm> using namespace std; const int ma ...
- 什么时候用created,什么时候用mounted
created 在实例创建完成后被立即调用.在这一步,实例已完成以下的配置:数据观测 (data observer), 属性和方法的运算,watch/event 事件回调.然而,挂载阶段还没开始,$e ...
- 研究发现:TLS1.3中的 TLS 对话恢复机制可以追踪用户
由于隐私浏览器技术的日渐成熟,网站越来越无法通过 Cookie 和网页浏览器特征来追踪用户,但道高一尺魔高一丈,现在这些网站会用 TLS 1.3 中的 TLS 对话恢复机制追踪用户. 你以为禁用浏览器 ...
- java中super和this用法总结
一.this用法 概念:this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的指针. this的用法在java中大致可以分为三种: 1. 普通对象的直接引用:this相当于指向当前对象本身 ...
- 序列模型(4)----门控循环单元(GRU)
一.GRU 其中, rt表示重置门,zt表示更新门. 重置门决定是否将之前的状态忘记.(作用相当于合并了 LSTM 中的遗忘门和传入门) 当rt趋于0的时候,前一个时刻的状态信息ht−1会被忘掉,隐藏 ...
- vue中使用base64进行加解密
vue进行Base64加解密 背景 项目中需要对特殊字符进行处理,避免json和数据库的特殊字符(""等)冲突,刚好学了信息安全,干脆整个加解密,wkk.. 使用步骤 打开dos, ...
- docker数据卷的使用 -v --volumes--from
总结一下docker数据管理的三种方法: 1.普通的挂在数据: -v docker run -v /father/path:/child/path-v 参数会把当前系统的文件目录/father/pa ...
- ubuntu的LAMP环境搭建
服务器的搭建,经典组合:LAMP(Linux+Apache+Mysql+PHP) unbuntu源更新:sudo apt update 更新:sudo apt upgrade 安装Apache:sud ...
- C#实现简单的串口通信
前言 本着学习研究的态度,用c#语言实现简单的串口通信工具. 一.串口通信原理 串口通信 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节.尽管比 ...
- ASP.NET学习笔记01
ASP.NET初级工程师的核心要求:能够实现一个基本的网站. ASP.NET初级工程师面试主要要求: 1.基础的数据结构和算法 2.C#编程语言基础 3.网站基础(HTML,CSS,Javascrip ...