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. binary-tree-maximum-path-sum——二叉树任意一条路径上的最大值

    Given a binary tree, find the maximum path sum. The path may start and end at any node in the tree. ...

  2. 建立第一个Sencha Touch应用

    准备 开始开发前,请先到下面的地址下载Sencha Touch 2的包:http://www.sencha.com/products/touch/download/ .下载完解压后你会发现包里有很多文 ...

  3. eclipse工具栏sdk和avd图标

    打开菜单Window -> Customize Perspective -> Command Groups Availability -> 勾选Android SDK and AVD ...

  4. JavaScript闭包其一:闭包概论 函数式编程中一些基本定义

    http://www.nowamagic.net/librarys/veda/detail/1707前面介绍了作用域链和变量对象,现在再讲闭包就容易理解了.闭包其实大家都已经谈烂了.尽管如此,这里还是 ...

  5. mysql存储过程之循环

    链接: http://www.blogjava.net/rain1102/archive/2011/05/16/350301.html

  6. PJSIP 调用的GUID库

    PJSIP库产生随机序列串用到GUID库,针对不同的平台使用的方式不同:Windows平台下使用的是Windows系统API CoCreateGuid,在方法 pj_generate_unique_s ...

  7. python訪问redis

    python訪问redis 1 Linux上安装redis a) 下载 $ wget http://download.redis.io/releases/redis-3.0.5.tar.gz b) 编 ...

  8. MySQL-获取某天的数据

    今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 近7天 DAY) <= date(时间字段名) 近30天 DAY) & ...

  9. ZOJ 3156 Taxi (二分匹配+二分查找)

    题目链接:Taxi Taxi Time Limit: 1 Second      Memory Limit: 32768 KB As we all know, it often rains sudde ...

  10. mysql 中创建递归函数

    1.在navicat中创建递归函数 BEGIN ) DEFAULT ''; ) default ''; ) default ''; ) default rootId; ; WHILE rootId i ...