定义多项式$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)的更多相关文章

  1. FFT模板 生成函数 原根 多项式求逆 多项式开根

    FFT #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> ...

  2. 2019.01.01 bzoj3625:小朋友和二叉树(生成函数+多项式求逆+多项式开方)

    传送门 codeforces传送门codeforces传送门codeforces传送门 生成函数好题. 卡场差评至今未过 题意简述:nnn个点的二叉树,每个点的权值KaTeX parse error: ...

  3. [Codeforces438E][bzoj3625] 小朋友和二叉树 [多项式求逆+多项式开根]

    题面 传送门 思路 首先,我们把这个输入的点的生成函数搞出来: $C=\sum_{i=0}^{lim}s_ix^i$ 其中$lim$为集合里面出现过的最大的数,$s_i$表示大小为$i$的数是否出现过 ...

  4. 【BZOJ3625】【codeforces438E】小朋友和二叉树 生成函数+多项式求逆+多项式开根

    首先,我们构造一个函数$G(x)$,若存在$k∈C$,则$[x^k]G(x)=1$. 不妨设$F(x)$为最终答案的生成函数,则$[x^n]F(x)$即为权值为$n$的神犇二叉树个数. 不难推导出,$ ...

  5. 【BZOJ3456】轩辕朗的城市规划 无向连通图计数 CDQ分治 FFT 多项式求逆 多项式ln

    题解 分治FFT 设\(f_i\)为\(i\)个点组成的无向图个数,\(g_i\)为\(i\)个点组成的无向连通图个数 经过简单的推导(枚举\(1\)所在的连通块大小),有: \[ f_i=2^{\f ...

  6. bzoj 3456 城市规划——分治FFT / 多项式求逆 / 多项式求ln

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3456 分治FFT: 设 dp[ i ] 表示 i 个点时连通的方案数. 考虑算补集:连通的方 ...

  7. P6295-有标号 DAG 计数【多项式求逆,多项式ln】

    正题 题目链接:https://www.luogu.com.cn/problem/P6295 题目大意 求所有\(n\)个点的弱联通\(DAG\)数量. \(1\leq n\leq 10^5\) 解题 ...

  8. BZOJ 3625 [Codeforces Round #250]小朋友和二叉树 ——NTT 多项式求逆 多项式开根

    生成函数又有奇妙的性质. $F(x)=C(x)*F(x)*F(x)+1$ 然后大力解方程,得到一个带根号的式子. 多项式开根有解只与常数项有关. 发现两个解只有一个是成立的. 然后多项式开根.求逆. ...

  9. luoguP4512 【模板】多项式除法 NTT+多项式求逆+多项式除法

    Code: #include<bits/stdc++.h> #define maxn 300000 #define ll long long #define MOD 998244353 # ...

随机推荐

  1. [知识梳理]课本3&9.1

    函数:关键词:参数.返回值.函数返回类型.函数体. 函数按照返回类型,可以分为有参函数和无参函数. 函数根据是否有返回值,可以分为返回值函数和非返回值函数.     函数的定义:函数的定义可以放在任意 ...

  2. 数据结构-线性表的链式存储相关算法(C语言实现)

    链表的简单介绍 为什么需要线性链表 当然是为了克服顺序表的缺点,在顺序表中,做插入和删除操作时,需要大量的移动元素,导致效率下降. 线性链表的分类 按照链接方式: 按照实现角度: 线性链表的创建和简单 ...

  3. kubernetes入门(01)kubernetes是什么?

    一.kubernetes是什么? Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署.大规模可伸缩.应用容器化管理.在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以 ...

  4. Spring Security入门(2-2)Spring Security 的运行原理 2

  5. BAT美团滴滴java面试大纲(带答案版)之三:多线程Lock

    继续面试大纲系列文章. 这是多线程的第二篇. 多线程就像武学中对的吸星大法,理解透了用好了可以得道成仙,俯瞰芸芸众生:而滥用则会遭其反噬. 在多线程编程中要渡的第二个“劫”,则是Lock.在很多时候, ...

  6. Linux命令(持续更新中)

    命令名 用法 安装上传下载 yum install lrzsz   rz上传文件,sz下载文件 压缩 解压文件 tar -zxvf  文件名 压缩文件 tar -zcvf 文件名 删除非空目录: rm ...

  7. tcpdump记录

    tcpdump -i eth0 -nn -A -X 'host 192.168.20.82 and port 9080' -i:interface 监听的网卡. -nn:表示以ip和port的方式显示 ...

  8. python基础——抽象类

    python基础--抽象类 1  什么是抽象类 与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化 2 为什么要有抽象 ...

  9. SpringMVC(二):RequestMapping修饰类、指定请求方式、请求参数或请求头、支持Ant路径

    @RequestMapping用来映射请求:RequestMapping可以修饰方法外,还可以修饰类 1)SpringMVC使用@RequestMapping注解为控制指定可以处理哪些URL请求: 2 ...

  10. Spring(2)——Spring IoC 详解

    Spring IoC 概述 IoC:Inverse of Control(控制反转) 读作"反转控制",更好理解,不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控 ...