fft

分治虽然是万能的,但是太慢了

分治是nlog^2n的,太慢了,于是我们用求逆和开根

设f(x)表示答案为x的方案数

c表示物品的生成函数

那么f=f*f*c+1

f*f表示左右儿子的方案数

c表示根的方案数

+1是空树,也就是+上t(x)=1这个生成函数

然后求根公式得出f=2/(1+sqrt(1-4*g))

为什么是+号呢?因为x=1时方案数=1,那么只能是+号

然后就是多项式开根和求逆

具体看picks博客

然后是卡常

所有数组开int

fft蝴蝶操作一定要开int

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int P = ;
ll power(ll x, int t)
{
ll ret = ;
for(; t; t >>= , x = x * x % P) if(t & ) ret = ret * x % P;
return ret;
}
const int N = ( << ) + ;
int n, k, m;
int rev[N];
ll inv2;
void ntt(int *a, int n, int k, int f)
{
for(int i = ; i < n; ++i) if(i < rev[i]) swap(a[i], a[rev[i]]);
for(int l = ; l <= n; l <<= )
{
ll w = power(, f == ? (P - ) / l : P - - (P - ) / l);
int m = l >> ;
for(int i = ; i < n; i += l)
{
ll t = ;
for(int k = ; k < m; ++k, t = t * w % P)
{
int x = a[i + k], y = t * a[i + k + m] % P;
a[i + k] = (x + y) % P;
a[i + m + k] = (x - y + P) % P;
}
}
}
if(f == -)
{
ll inv = power(n, P - );
for(int i = ; i < n; ++i) a[i] = a[i] * inv % P;
}
}
int a[N], b[N], tmp[N], B[N], c[N];
void poly_inverse(int *a, int *b, int l)
{
if(l == )
{
b[] = power(a[], P - );
return;
}
poly_inverse(a, b, l >> );
int n = , k = ;
while(n <= l) n <<= , ++k;
for(int i = ; i < n; ++i) rev[i] = (rev[i >> ] >> ) | ((i & ) << (k - ));
for(int i = ; i < l; ++i) tmp[i] = a[i];
for(int i = l; i < n; ++i) tmp[i] = ;
ntt(tmp, n, k, );
ntt(b, n, k, );
for(int i = ; i < n; ++i) b[i] = (ll)b[i] * ( - (ll)tmp[i] * b[i] % P + P) % P;
ntt(b, n, k, -);
for(int i = l; i < n; ++i) b[i] = ;
}
void poly_sqrt(int *a, int *b, int l)
{
if(l == )
{
b[] = ;
return;
}
int n = , k = ;
while(n <= l) n <<= , ++k;
poly_sqrt(a, b, l >> );
for(int i = ; i < n; ++i) B[i] = ;
poly_inverse(b, B, l);
for(int i = ; i < n; ++i) rev[i] = (rev[i >> ] >> ) | ((i & ) << (k - ));
for(int i = ; i < l; ++i) tmp[i] = a[i];
for(int i = l; i < n; ++i) tmp[i] = , B[i] = ;
ntt(B, n, k, );
ntt(tmp, n, k, );
ntt(b, n, k, );
for(int i = ; i < n; ++i) b[i] = (ll)inv2 * (b[i] + (ll)B[i] * tmp[i] % P) % P;
ntt(b, n, k, -);
for(int i = l; i < n; ++i) b[i] = ;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i)
{
int x;
scanf("%d", &x);
c[x] -= ;
}
inv2 = power(, P - );
int len = ;
while(len <= m) len <<= ;
++c[];
for(int i = ; i <= m; ++i) if(c[i] < ) c[i] += P;
poly_sqrt(c, b, len);
++b[];
b[] %= P;
poly_inverse(b, a, len);
for(int i = ; i <= m; ++i) printf("%d\n", a[i] * % P);
return ;
}

bzoj3625的更多相关文章

  1. 【bzoj3625】【xsy1729】小朋友和二叉树

    [bzoj3625]小朋友与二叉树 题意 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. 考虑一个含有n个互异正整数的序列c[1],c[2],...,c[n].如果一棵带点权的有根二叉树满足其所有 ...

  2. 【BZOJ3625】【CF438E】小朋友和二叉树 NTT 生成函数 多项式开根 多项式求逆

    题目大意 考虑一个含有\(n\)个互异正整数的序列\(c_1,c_2,\ldots ,c_n\).如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合\(\{c_1,c_2,\ldots ,c_n\ ...

  3. BZOJ3625 [Codeforces Round #250]小朋友和二叉树(生成函数+多项式开根)

    设f(n)为权值为n的神犇二叉树个数.考虑如何递推求这个东西. 套路地枚举根节点的左右子树.则f(n)=Σf(i)f(n-i-cj),cj即根的权值.卷积的形式,cj也可以通过卷上一个多项式枚举.可以 ...

  4. 【BZOJ3625/CF438E】小朋友和二叉树(多项式求逆,多项式开方)

    [BZOJ3625/CF438E]小朋友和二叉树(多项式求逆,多项式开方) 题面 BZOJ CodeForces 大致题意: 对于每个数出现的次数对应的多项式\(A(x)\) 求\[f(x)=\fra ...

  5. [bzoj3625][Codeforces 250 E]The Child and Binary Tree(生成函数+多项式运算+FFT)

    3625: [Codeforces Round #250]小朋友和二叉树 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 650  Solved: 28 ...

  6. BZOJ3625: [Codeforces Round #250]小朋友和二叉树

    Description 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树.考虑一个含有n个互异正整数的序列c[1],c[2],...,c[n].如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合{ ...

  7. NTT+多项式求逆+多项式开方(BZOJ3625)

    定义多项式$h(x)$的每一项系数$h_i$,为i在c[1]~c[n]中的出现次数. 定义多项式$f(x)$的每一项系数$f_i$,为权值为i的方案数. 通过简单的分析我们可以发现:$f(x)=\fr ...

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

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

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

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

  10. BZOJ3625: 小朋友和二叉树

    传送门 Sol 设 \(f_x\) 表示权值为 \(x\) 的二叉树的个数 设 \(s_x\) 表示是否有 \(x\) 这种权值可以选择 那么 \[f_n=\sum_{i=0}^{n}\sum_{j= ...

随机推荐

  1. SwitchyOmega 代理设置

    1.SwitchyOmega官网 https://www.switchyomega.com/ 2.下载插件 https://www.switchyomega.com/download.html 3.配 ...

  2. adb命令具体解释(二)——手机缺失sqlite3时操作数据库的多种解决方式

    在android应用开发无处不在SQLite数据库的身影.那么在开发中怎么使用adb命令操作数据库的功能呢? 以下我们将完整的介绍与数据库操作相关的命令集及当手机缺少sqlite3的时候的多种解决方式 ...

  3. 【Sprint3冲刺之前】TDzhushou软件项目测试计划书

    TDzhushou软件测试计划文档 文档编号:2014-5-8 产品版本:1.1 产品名称:TDzhushou 文 档 作 者: 解凤娇       日期:2014-5-4 软件测试计划 目录 第一章 ...

  4. Android 中View仅仅能接收到ACTION_DOWN无法接收ACTION_MOVE和ACTION_UP解决的方法

    昨天晚上调试了一晚上,在LinearLayout上接收屏幕动作,可是出现了问题, 以下的代码是本人调的代码 </pre><pre name="code" clas ...

  5. 不使用flash实现复制文字(图片)到剪贴板

    <div>这里是待复制的文字或图片</div> var range = document.createRange(); var referenceNode = document ...

  6. .NET MVC 4 实现用户注册功能

    初学MVC,踩了不少坑,所以通过实现一个用户注册功能把近段时间学习到的知识梳理一遍,方便以后改进和查阅. 问题清单: l 为什么EF自动生成的表名后自动添加了s? l 如何为数据库初始化一些数据? l ...

  7. javascript点滴积累

    1. javascript中的array, set, map 均为数据容器,使用iterable内置的forEach方法 var a = ['A', 'B', 'C'];a.forEach(funct ...

  8. c结构体里的数组与指针

    /* 訪问成员数组名事实上得到的是数组的相对地址.而訪问成员指针事实上是相对地址里的内容 */ struct buf_str { int length; char buf[0]; }; struct ...

  9. HDFS被设计成能够在一个大集群中跨机器可靠地存储超大文件

    HDFS被设计成能够在一个大集群中跨机器可靠地存储超大文件.它将每个文件存储成一系列的数据块,除了最后一个,所有的数据块都是同样大小的.为了容错,文件的所有数据块都会有副本.每个文件的数据块大小和副本 ...

  10. (转)Android--UI之ImageView

    前言 这篇博客聊一聊在Android下ImageView的使用,在此篇博客中,会讲解到ImageView的一些属性的使用,以及ImageView展示图片的放大.缩小.旋转等操作.最后再讲解一下Andr ...