NTT+多项式求逆+多项式开方(BZOJ3625)
定义多项式$h(x)$的每一项系数$h_i$,为i在c[1]~c[n]中的出现次数。
定义多项式$f(x)$的每一项系数$f_i$,为权值为i的方案数。
通过简单的分析我们可以发现:$f(x)=\frac{2}{\sqrt{1-4h(x)}+1}$
于是我们需要多项式开方和多项式求逆。
多项式求逆:
求$B(x)$,使得$A(x)*B(x)=1\;(mod\;x^m)$
考虑倍增。
假设我们已知$A(x)*B(x)=1\;(mod\;x^m)$,要求$C(x)$,使得$A(x)*C(x)=1\;(mod\;x^{2m})$
简单分析可得$C(x)=B(x)*(2-A(x)*B(x))$
多项式开方:
求$B(x)$,使得$B(x)*B(x)=A(x)\;(mod\;x^m)$
继续考虑倍增。
假设我们已知$B(x)*B(x)=A(x)\;(mod\;x^m)$,要求$C(x)$,使得$C(x)*C(x)=A(x)\;(mod\;x^{2m})$
简单分析可得$C(x)=\frac{B(x)^2+A(x)}{2B(x)}$,需要求$B(x)$的逆。
观察到以上两个式子都用到了多项式乘法,又因为在模意义下,我们需要NTT。
NTT和FFT的区别在于单位根不一样,NTT需要找一个p的原根,而且通常要求p是形如$k*2^q+1$的一个质数。
找原根暴力找就行了。
(这题卡常数,所以我都用的int)
#include <cstdio>
#include <cstring>
#include <algorithm> typedef long long ll;
const int N=,p=;
int n,m,x,ni,r[N],h[N],_h[N],__h[N],t[N];
ll pw(ll a,int b) {
ll r=;
for(;b;b>>=,a=a*a%p) if(b&) r=r*a%p;
return r;
} void ntt(int *a,int n,int f) {
for(int i=;i<n;i++) if(r[i]>i) std::swap(a[i],a[r[i]]);
for(int i=;i<=n;i<<=)
for(int j=,wn=pw(,((p-)/i*f+p-)%(p-)),m=i>>;j<n;j+=i)
for(int k=,w=;k<m;k++,w=(ll)w*wn%p) {
int x=a[j+k],y=(ll)a[j+k+m]*w%p;
a[j+k]=(x+y)%p,a[j+k+m]=(x-y+p)%p;
}
if(f==-) {
ll ni=pw(n,p-);
for(int i=;i<n;i++) a[i]=(ll)a[i]*ni%p;
}
}
void gt2(int n) {
if(n==) {__h[]=pw(_h[],p-); return;}
gt2(n>>),memcpy(t,_h,sizeof(int)*n),memset(t+n,,sizeof(int)*n);
int m=,l=-;
while(m<n<<) m<<=,l++;
for(int i=;i<m;i++) r[i]=(r[i>>]>>)|((i&)<<l);
ntt(t,m,),ntt(__h,m,);
for(int i=;i<m;i++) __h[i]=(ll)__h[i]*(-(ll)t[i]*__h[i]%p+p)%p;
ntt(__h,m,-),memset(__h+n,,sizeof(int)*n);
}
void gt(int n) {
if(n==) {_h[]=; return;}
gt(n>>),memset(__h,,sizeof(int)*n),gt2(n);
memcpy(t,h,sizeof(int)*n),memset(t+n,,sizeof(int)*n);
int l=-,m=;
while(m<n<<) m<<=,l++;
for(int i=;i<m;i++) r[i]=(r[i>>]>>)|((i&)<<l);
ntt(t,m,),ntt(_h,m,),ntt(__h,m,);
for(int i=;i<m;i++) _h[i]=((ll)_h[i]*_h[i]+t[i])%p*__h[i]%p*ni%p;
ntt(_h,m,-),memset(_h+n,,sizeof(int)*n);
} int main() {
scanf("%d%d",&m,&n),ni=pw(,p-);
for(int i=;i<=m;i++) scanf("%d",&x),h[x]++;
for(int i=;i<=n;i++) h[i]=(-h[i]*+p)%p;
for(m=n,n=;n<=m;n<<=);
h[]++,gt(n),_h[]=(_h[]+)%p,memset(__h,,sizeof __h),gt2(n);
for(int i=;i<=m;i++) printf("%d\n",__h[i]*%p);
return ;
}
NTT+多项式求逆+多项式开方(BZOJ3625)的更多相关文章
- FFT模板 生成函数 原根 多项式求逆 多项式开根
FFT #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> ...
- 2019.01.01 bzoj3625:小朋友和二叉树(生成函数+多项式求逆+多项式开方)
传送门 codeforces传送门codeforces传送门codeforces传送门 生成函数好题. 卡场差评至今未过 题意简述:nnn个点的二叉树,每个点的权值KaTeX parse error: ...
- [Codeforces438E][bzoj3625] 小朋友和二叉树 [多项式求逆+多项式开根]
题面 传送门 思路 首先,我们把这个输入的点的生成函数搞出来: $C=\sum_{i=0}^{lim}s_ix^i$ 其中$lim$为集合里面出现过的最大的数,$s_i$表示大小为$i$的数是否出现过 ...
- 【BZOJ3625】【codeforces438E】小朋友和二叉树 生成函数+多项式求逆+多项式开根
首先,我们构造一个函数$G(x)$,若存在$k∈C$,则$[x^k]G(x)=1$. 不妨设$F(x)$为最终答案的生成函数,则$[x^n]F(x)$即为权值为$n$的神犇二叉树个数. 不难推导出,$ ...
- 【BZOJ3456】轩辕朗的城市规划 无向连通图计数 CDQ分治 FFT 多项式求逆 多项式ln
题解 分治FFT 设\(f_i\)为\(i\)个点组成的无向图个数,\(g_i\)为\(i\)个点组成的无向连通图个数 经过简单的推导(枚举\(1\)所在的连通块大小),有: \[ f_i=2^{\f ...
- bzoj 3456 城市规划——分治FFT / 多项式求逆 / 多项式求ln
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3456 分治FFT: 设 dp[ i ] 表示 i 个点时连通的方案数. 考虑算补集:连通的方 ...
- P6295-有标号 DAG 计数【多项式求逆,多项式ln】
正题 题目链接:https://www.luogu.com.cn/problem/P6295 题目大意 求所有\(n\)个点的弱联通\(DAG\)数量. \(1\leq n\leq 10^5\) 解题 ...
- BZOJ 3625 [Codeforces Round #250]小朋友和二叉树 ——NTT 多项式求逆 多项式开根
生成函数又有奇妙的性质. $F(x)=C(x)*F(x)*F(x)+1$ 然后大力解方程,得到一个带根号的式子. 多项式开根有解只与常数项有关. 发现两个解只有一个是成立的. 然后多项式开根.求逆. ...
- luoguP4512 【模板】多项式除法 NTT+多项式求逆+多项式除法
Code: #include<bits/stdc++.h> #define maxn 300000 #define ll long long #define MOD 998244353 # ...
随机推荐
- 【微软大法好】VS Tools for AI全攻略(2)
接着上文,我们来讨论如何使用Azure资源来训练我们的tensorflow项目.Azure云我个人用得很多,主要是因为微软爸爸批了150刀每月的额度,我可以愉快地玩耍. 那么针对Azure,有成套的两 ...
- LeetCode & Q26-Remove Duplicates from Sorted Array-Easy
Descriptions: Given a sorted array, remove the duplicates in place such that each element appear onl ...
- Oracle闪回技术
(一)闪回技术概要 闪回技术是数据库备份与恢复的重要补充手段,主要包括以下7种特性: 特性 原理 数据库支持 闪回查询(Flashback Query) 利用undo表空间中的回退信息,查询过去某个时 ...
- WIN10系统触摸板快捷键
快捷的手势操作,有时候会让人脱离鼠标,只要不是非用不可的情况,基本上这些常用手势就能让我们摆脱鼠标携带不便或者桌子地方小的烦恼.iOS上的快捷手势很是受欢迎,win10上却鲜有人知晓,尤其是非开发人员 ...
- java中类的三大特征之多态
Java 多态 同一种事物由于条件不同,展示出不同的结果,叫做多态. 父类的引用类型,由于使用不同的子类对象实例,而执行不同的操作. 多态存在的三个必要条件 1. 子类继承父类: 2. 子类重写父类方 ...
- EasyUI 冻结列
一.如果是js绘制的,设置frozenColumn属性就可以,frozenColumn 属性和 columns 属性都是设置列,frozenColumn是设置冻结列 $('#tt').datagrid ...
- DevExpress 控件中GridControl的使用
近期开发用到了DevExpress系列的控件,GridControl是我用到的Dev系列控件最多的一个控件.现在先来总结一下: 首先先写一个简单的小例子来简单介绍一下GridControl的用法: 1 ...
- python多进程--------linux系统中python的os.fork()方法
linux下python 创建子进程的原理: os.fork()方法 的原理 为了实现并发.多任务,我们可以在主程序种开启一个进程或者线程.在类unix操作系统当中(非windows),可以用pyth ...
- Python之面向对象四
面向对象进阶 一.关于面向对象的两个内置函数 isinstance 判断类与对象的关系 isinstance(obj,cls)检查obj是否是类 cls 的对象,返回值是bool值 issu ...
- API验证及AES加密
API验证 API验证: a. 发令牌: 静态 PS: 隐患 key被别人获取 b. 动态令牌 PS: (问题越严重)用户生成的每个令牌被黑客获取到,都会破解 c. 高级版本 PS: 黑客网速快,会窃 ...