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. Odoo 运费

    模块delievery可以将运费Charge给客户     安装delivery模块                 Delivery method     在做订单的时候,选择相应的运输方法, 系统 ...

  2. leetcode第一刷_Permutation Sequence

    这道题还挺好的,假设你的思路是每次生成一个全排列,然后累计到k次,那么停下来吧.肯定超时了亲.. 微软今年的笔试题里有一道类似的,我之前已经提到过了.是唯独0和1的字符串,求第k个排列是什么样子的.这 ...

  3. idea常用的快捷命令

    main方法: psvm System.out.println(): sout

  4. svn 命令个

    svn 命令行下常用的几个命令 标签: svnpathdelete工作urlfile 2011-11-28 08:16 128627人阅读 评论(1) 收藏 举报  分类: 版本控制(8)  版权声明 ...

  5. Andriod三步学会安卓自己定义视图及其属性

    第一步:自己定义属性 第二步:自己定义控件解析属性 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcm5adW9adW8=/font/5a6L5L2T/fo ...

  6. beifen---http://vdisk.weibo.com/s/uhCtnyUhD0Ooc

  7. 将UIBezierPath存为自己定义格式的字符串,再将字符串转为UIBezierPath

    <pre name="code" class="objc">自己定义字符串格式为:@"123.02,234.23|321.23,432.0 ...

  8. HBase写请求分析

    HBase作为分布式NoSQL数据库系统,不单支持宽列表.而且对于随机读写来说也具有较高的性能.在高性能的随机读写事务的同一时候.HBase也能保持事务的一致性. 眼下HBase仅仅支持行级别的事务一 ...

  9. Arrays.sort(a) 自定义排序

     Arrays.sort(a) 自定义排序,(需实现接口:Comparable) package com.hd; import java.util.Arrays; class Person imple ...

  10. db2 命令

    很久没有些博客了.把以前用到的操作 DB2 的命令发表下可能有很多人已经发布了.就当是自己做下功课吧,以备有用之需. 1. 打开命令行窗口 #db2cmd 2. 打开控制中心 # db2cmd db2 ...