题目

传送门

思路&做法

我们可以用\(v_i\)表示\(i\)在\(c\)中出现了几次, 用\(f_i\)表示权值为\(i\)的神犇树的总数, 于是

\[f_x = \sum_{i = 0}^{x}v_i \bigg( \sum_{j = 0}^{x-i}f_jf_{x-i-j} \bigg)
\]

\[f_0 = 1
\]

然后我们设\(v\)的生成函数为\(V = \sum_{i = 0} ^{\infty}v_ix^i\),

设\(f\)的生成函数为\(F = \sum_{i = 0}^{\infty}f_ix^i\)

所以

\[F(x) = C(x) F(x)F(x) + 1
\]

然后移一下项

\[V(x)F^2(x) - F(x) + 1 = 0
\]

接着直接用求根公式

\[F(x) = {1 \pm \sqrt{1 - 4 \times V(x)} \over 2 \times V(x)}
\]

于是有两种情况

\((1)\)

\[F(x) = {1 + \sqrt{1 - 4 \times V(x)} \over 2 \times V(x)}
\]

要舍去\((\)原因?不知道,我太弱了\()\)

\((2)\)

\[F(x) = {1 - \sqrt{1 - 4 \times V(x)} \over 2 \times V(x)}
\]

可以把分子和分母同时乘上\(1 + \sqrt{1 + 4 \times V(x)}\)

所以

\[\begin {aligned}
F(x)&={1^2 - \big(\sqrt{1 - 4 \times V(x)}\big)^2 \over {2 \times V(x) \times \big(1 + \sqrt{1 - 4 \times V(x)} \big)}} \\\
&={4 \times V(x) \over {2 \times V(x) \times \big(1 + \sqrt{1 - 4 \times V(x)}} \big)} \\\
&={2 \over {1 + \sqrt{1 - 4 \times V(x)}}}
\end {aligned}
\]

多项式求逆和多项式开根可以看我的这篇blog : 多项式的一些东西

代码

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm> using namespace std; typedef long long LL; const LL mod = 998244353LL; const int N = 400010; char I[8000010], *pos, *End; inline char GetChar()
{ if(pos == End)
{ End = (pos = I) + fread(I, 1, 8000000, stdin);
if(pos == End) return EOF;
}
return *pos++;
} inline int rd_int()
{ int x = 0, f = 1;
char c = GetChar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = GetChar(); }
while(c >= '0' && c <= '9') { x = x*10 + c-'0'; c = GetChar(); }
return x*f;
} int Bit; inline LL power(LL a, LL n)
{ LL ans = 1;
while (n)
{ if (n & 1) ans = (ans * a) % mod;
a = (a * a) % mod;
n >>= 1;
}
return ans;
} int rev[N]; void getReverse(int Len)
{ for (int i = 0; i < Len; i++)
rev[i] = (rev[i>>1] >> 1) | ((i&1) * (Len>>1));
} LL w_n[N]; void NTT(LL * a, int opt, int Len)
{ getReverse(Len);
for (int i = 0; i < Len; i++)
if (i < rev[i]) swap(a[i], a[rev[i]]);
for (register int i = 2; i <= Len; i <<= 1)
{ LL w_n = power(3LL, (mod-1LL) / (LL)i);
if (opt == -1) w_n = power(w_n, mod-2);
for (register int j = 0; j < Len; j += i)
{ LL w = 1;
for (register int k = 0; k < (i>>1); k++)
{ LL x = a[j + k];
LL y = (w * a[j + k + (i>>1)]) % mod;
a[j + k] = (x + y) % mod;
a[j + k + (i>>1)] = (x - y + mod) % mod;
w = (w * w_n) % mod;
}
}
}
if (opt == -1)
{ LL num = power(Len, mod-2);
for (register int i = 0; i < Len; i++)
a[i] = (a[i] * num) % mod;
}
} int getBit(int l)
{ Bit = 0;
for (; (1 << Bit) <= l; Bit++);
} inline void cpy(LL * a, LL * b, int n, int Len)
{ for (register int i = 0; i < n; i++) a[i] = b[i];
for (register int i = n; i < Len; i++) a[i] = 0;
} LL tmp1[N], tmp2[N]; void get_Inv(LL * a, LL * b, int l)
{ b[0] = power(a[0], mod-2);
for (register int i = 2; i <= l; i <<= 1)
{ int Len = i << 1;
cpy(tmp1, a, i, Len);
cpy(tmp2, b, i>>1, Len);
NTT(tmp1, 1, Len);
NTT(tmp2, 1, Len);
for (register int j = 0; j < Len; j++)
tmp1[j] = ((2LL*tmp2[j])%mod + mod - (((tmp2[j]*tmp2[j])%mod)*tmp1[j])%mod) % mod;
NTT(tmp1, -1, Len);
for (register int j = 0; j < i; j++)
b[j] = tmp1[j];
}
} LL inv2; LL tmp3[N], tmp4[N], tmp5[N]; void Sqrt(LL * a, LL * b, int l)
{ b[0] = 1;
for (register int i = 1; i <= l; i <<= 1)
{ int Len = i << 1;
for (register int j = 0; j < Len; j++)
if (j < i) tmp3[j] = (2LL * b[j]) % mod;
else tmp3[j] = 0;
get_Inv(tmp3, tmp4, i);
for (register int j = i; j < Len; j++) tmp4[j] = 0;
cpy(tmp5, a, i, Len);
NTT(tmp4, 1, Len);
NTT(tmp5, 1, Len);
for (register int j = 0; j < Len; j++)
tmp4[j] = (tmp4[j] * tmp5[j]) % mod;
NTT(tmp4, -1, Len);
for (register int j = 0; j < (i << 1); j++)
b[j] = (inv2 * b[j] + tmp4[j]) % mod;
}
} LL a[N], b[N], ans[N]; LL v[N]; int main()
{ int n, m;
n = rd_int(), m = rd_int();
m++;
for (register int i = 1; i <= n; i++)
{ int x;
x = rd_int();
v[x]++;
}
inv2 = power(2, mod - 2);
getBit(m);
a[0] = 1;
for (register int i = 1; i < m; i++)
a[i] = (4 * (mod - v[i])) % mod;
Sqrt(a, b, (1 << Bit));
b[0] = (b[0] + 1) % mod;
get_Inv(b, ans, (1 << Bit));
for (register int i = 1; i < m; i++)
printf("%lld\n", (ans[i] * 2LL) % mod);
return 0;
}

【BZOJ3625】【CF438E】小朋友和二叉树的更多相关文章

  1. [BZOJ3625][CF438E]小朋友和二叉树

    题面 Description 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. 考虑一个含有\(n\)个互异正整数的序列\(c_1,c_2,\ldots,c_n\).如果一棵带点权的有根二叉树满足其 ...

  2. [BZOJ3625][CF438E]小朋友和二叉树 (多项式开根,求逆)

    题面 题解 设多项式的第a项为权值和为a的二叉树个数,多项式的第a项表示是否为真,即 则,所以F是三个多项式的卷积,其中包括自己: ,1是F的常数项,即. 我们发现这是一个一元二次方程,可以求出,因为 ...

  3. BZOJ3625 CF438E 小朋友与二叉树

    心态崩了 不放传送门了 辣鸡bz 还是正经一点写一下题解= = 就是显然我们可以把权值写成生成函数形式g(0/1序列)来表示权值是否出现 然后f来表示总的方案数 可以列出 分别枚举左右子树和空树的情况 ...

  4. [CF438E] 小朋友和二叉树

    Description 给定一个整数集合 \(c\),对于每个 \(i\in[1,m]\),求有多少种不同的带点权的二叉树使得这棵树点权和为 \(i\) 并且顶点的点权全部在集合 \(c\) 中.\( ...

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

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

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

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

  7. 【CF438E】小朋友和二叉树 解题报告

    [CF438E]小朋友和二叉树 Description ​ 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. ​ 考虑一个含有\(n\)个互异正整数的序列\(c_1,c_2,\dots,c_n\). ...

  8. BZOJ 3625: [Codeforces Round #250]小朋友和二叉树

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

  9. 「BZOJ 3645」小朋友与二叉树

    「BZOJ 3645」小朋友与二叉树 解题思路 令 \(G(x)\) 为关于可选大小集合的生成函数,即 \[ G(x)=\sum[i\in c ] x^i \] 令 \(F(x)\) 第 \(n\) ...

  10. [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)

    [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...

随机推荐

  1. solr相关文章

    Solr集群架构概述及delta-import详细配置 背景 由于项目原因,重新熟悉了下Solr,版本为3.6,搭建了主从Solr服务,并使用DIH从RDBMS数据源增量更新索引. 其实也没什么技术含 ...

  2. Django学习之 - 基础部分

    学习记录参考: 讲师博客:http://www.cnblogs.com/wupeiqi/articles/5433893.html 老男孩博客:http://oldboy.blog.51cto.com ...

  3. T1365 浴火银河星际跳跃 codevs

    http://codevs.cn/problem/1365/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 小 K 又在玩浴 ...

  4. Spring Cloud(8):Sleuth和Zipkin的使用

    场景: 某大型电商网站基于微服务架构,服务模块有几十个. 某天,测试人员报告该网站响应速度过慢.排除了网络问题之后,发现很难进一步去排除故障. 那么:如何对微服务的链路进行监控呢? Sleuth: 一 ...

  5. redis连接数据库进行操作

    该项目需要的类目录 1.首先我们需要创建我们的实体类 2.放置我们的dao层,在里面写入方法 3.配置类Appconfig需要加入我们的JdbcTemplate方法,因为我们用的是spring,所以需 ...

  6. win8,win10里面内置的IE浏览器网银无法输入密码

    win8,win10里面内置的IE浏览器网银无法输入密码,安装控件也没效果,部分网银直接导致IE崩溃,只需要简单设置即可解决. 方法/步骤   1 打开IE浏览器,点击右上角的小齿轮图标,在下拉菜单中 ...

  7. 【Nginx】如何建立新连接

    处理新连接事件的回调函数是ngx_event_accept,原型如下: void ngx_event_accept(ngx_event_t *ev) 具体流程如下: 1)首先调用accept方法试图建 ...

  8. Windows——cmd findstr 字符串查找增强使用说明

    在文件中寻找字符串. 复制代码代码如下: FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file] [ ...

  9. Ubuntu使用adb连接android手机失败unknown的解决的方法

    Ubuntu使用adb连接android手机失败unknown的解决的方法   Ubuntu下通过USB数据线连接G11手机后,adb可能无法识别到设备.依照一下步骤能够解决此问题. 1.在termi ...

  10. Unity5的关卡切换

    本文章由cartzhang编写,转载请注明出处. 全部权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/51055584 作者:car ...