定义多项式$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. C语言Linix服务器网络爬虫项目(二)项目设计和通过一个http请求抓取网页的简单实现

    我们通过上一篇了解了爬虫具体要实现的工作之后,我们分析得出的网络爬虫的基本工作流程如下: 1.首先选取一部分精心挑选的种子URL: 2.将这些URL放入待抓取URL队列: 3.从待抓取URL队列中取出 ...

  2. kafka---broker 保存消息

    1 .存储方式 物理上把 topic 分成一个或多个 patition(对应 server.properties 中的 num.partitions=3 配置),每个 patition 物理上对应一个 ...

  3. 使用nodeJS的 crypto模块来为你的密码hash加盐

    这篇文章将向你解释如何使用Node.js的Crypto模块对你的密码进行加盐hash.在这里,我们将不会对不懂的密码存储方式进行详细的比较.我们将要做的是知道在Node.js中使用加盐hash在进行密 ...

  4. slf4j入门

    一.官方说明: The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for vari ...

  5. golang微信公众号请求获取信息

    初次用golang在公众号中获取信息,记录一下 看了下文档,粗略的写了个demo,如下: func HttpGet(c*gin.Context) { var param GetType if er:= ...

  6. python/零起点(一、列表)

    python/零起点(一.列表) 列表(list)list()可以强行转换数据类型为列表,列表是可迭代对象 列表是有序的,且列表是可变的数据类型 列表中的元素可以是(字符串.整型.元祖.列表.字典.集 ...

  7. Hibernate(四):Hello World

    下载hibernate开发包: 在本章之前需要继承hibernate开发插件到eclipse,详细操作请参考我的博文:<Hibernate(一):安装hibernate插件到eclipse环境& ...

  8. Frame

    Frame意为框架,是在屏幕上的一个矩形区域. Frame主要作为其他组件的框架基础,或为其他组件提供间距补充. 何时使用Frame组件呢? Frame组件主要用于在复杂的布局中奖其他组件分组,也用于 ...

  9. jacascript 函数参数与 arguments 对象

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 调用函数时,实参和形参需要一一对应,但如果参数多了的话,会很苦恼: 我们可以用键值对(字面量对象)的方式传 ...

  10. 00-翻译IdentityServer4的目的

    强迫自己阅读英文文档 加深IdentityServer4的概念认识