CF 438E The Child and Binary Tree
BZOJ 3625
吐槽
BZOJ上至今没有卡过去,太慢了卡得我不敢交了……
一件很奇怪的事情就是不管是本地还是自己上传数据到OJ测试都远远没有到达时限。
本题做法
设$f_i$表示权值为$i$的二叉树的个数,因为一棵二叉树可以通过左右儿子构建起来转移,我们可以得到转移:
$$f_w = \sum_{x, y, w - (x + y) \in c} f_x * f_y$$
注意到左右子树可以为空,所以$f_0 = 1$。
很容易发现这是一个卷积的形式,我们尝试把它写得好看一点。
先把物品写成生成函数的形式,记
$$G(x) = \sum_{i = 0}^{m}[i \in c]x^i$$
题目保证了$G(0) = 0$。
再用$F(x)$表示权值为$x$的二叉树的个数,有
$$F(n) = \sum_{i = 1}^{n}G(i)\sum_{j = 1}^{n - i}F(j)F(n - i - j)$$
$$F(n) = (G * F ^ 2)(n)$$
发现多项式$F$除了第$0$项每一项都可以由上面这个式子得到,而$F(0) = 1$。
得到
$$F = G * F ^ 2 + 1$$
解一元二次方程,
$$F = \frac{2}{1 \pm \sqrt{1 - 4G}}$$
考虑到$G(0) = 0$,$F(0) = 1$,所以取加号。
剩下就是怎么开根的问题。
多项式开根
假设已经求出了$F_0(x)$使$G(F_0(x)) \equiv 0 (\mod x^{\left \lceil \frac{n}{2} \right \rceil})$成立,要求$F(x)$使$G(F(x)) \equiv 0 (\mod x^n)$成立。
在多项式$exp$那里已经提过了这里$G(F(x)) = F(x)^2 - A(x)$。
牛顿迭代的式子拿出来,
$$F(x) \equiv F_0(x) - \frac{G(F_0(x))}{G'(F_0(x))}( \mod x^n)$$
$$G'(F(x)) = 2F(x)$$
代进去
$$F(x) \equiv \frac{F_0(x)^2 + A(x)}{2F_0(x)}(\mod x^n)$$
可以递归计算了。
$$T(n) = T(\frac{n}{2}) + O(nlogn)$$
时间复杂度还是$O(nlogn)$,常数极大就是了。
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll; const int N = << ; int n, m, a[N];
ll f[N], g[N]; namespace Poly {
const int L = << ;
const ll P = 998244353LL; int lim, pos[L];
ll f[L], g[L], h[L], tmp[L]; inline ll fpow(ll x, ll y) {
ll res = ;
for (x %= P; y > ; y >>= ) {
if (y & ) res = res * x % P;
x = x * x % P;
}
return res;
} const ll inv2 = fpow(, P - ); inline void prework(int len) {
int l = ;
for (lim = ; lim < len; lim <<= , ++l);
for (int i = ; i < lim; i++)
pos[i] = (pos[i >> ] >> ) | ((i & ) << (l - ));
} inline void ntt(ll *c, int opt) {
for (int i = ; i < lim; i++)
if (i < pos[i]) swap(c[i], c[pos[i]]);
for (int i = ; i < lim; i <<= ) {
ll wn = fpow(, (P - ) / (i << ));
if (opt == -) wn = fpow(wn, P - );
for (int len = i << , j = ; j < lim; j += len) {
ll w = ;
for (int k = ; k < i; k++, w = w * wn % P) {
ll x = c[j + k], y = w * c[j + k + i] % P;
c[j + k] = (x + y) % P, c[j + k + i] = (x - y + P) % P;
}
}
} if (opt == -) {
ll inv = fpow(lim, P - );
for (int i = ; i < lim; i++) c[i] = c[i] * inv % P;
}
} void inv(ll *a, ll *b, int len) {
if (len == ) {
b[] = fpow(a[], P - );
return;
} inv(a, b, (len + ) >> );
prework(len << );
for (int i = ; i < lim; i++) f[i] = g[i] = ;
for (int i = ; i < len; i++) f[i] = a[i], g[i] = b[i];
ntt(f, ), ntt(g, );
for (int i = ; i < lim; i++)
g[i] = g[i] * (2LL - g[i] * f[i] % P + P) % P;
ntt(g, -); for (int i = ; i < len; i++) b[i] = g[i];
} inline void direv(ll *c, int len) {
for (int i = ; i < len - ; i++) c[i] = c[i + ] * (i + ) % P;
c[len - ] = ;
} inline void integ(ll *c, int len) {
for (int i = len - ; i > ; i--) c[i] = c[i - ] * fpow(i, P - ) % P;
c[] = ;
} inline void ln(ll *a, ll *b, int len) {
for (int i = ; i < len; i++) h[i] = ;
inv(a, h, len); for (int i = ; i < len; i++) b[i] = a[i];
direv(b, len); prework(len << );
ntt(h, ), ntt(b, );
for (int i = ; i < lim; i++) b[i] = b[i] * h[i] % P;
ntt(b, -); integ(b, len);
} ll F[L], G[L], H[L];
void exp(ll *a, ll *b, int len) {
if (len == ) {
b[] = ;
return;
}
exp(a, b, (len + ) >> ); ln(b, F, len);
F[] = (a[] % P + - F[] + P) % P;
for (int i = ; i < len; i++) F[i] = (a[i] - F[i] + P) % P; prework(len << );
for (int i = len; i < lim; i++) F[i] = ;
for (int i = ; i < lim; i++) G[i] = ;
for (int i = ; i < len; i++) G[i] = b[i];
ntt(F, ), ntt(G, );
for (int i = ; i < lim; i++) F[i] = F[i] * G[i] % P;
ntt(F, -); for (int i = ; i < len; i++) b[i] = F[i];
} void sqr(ll *a, ll *b, int len) {
if (len == ) {
b[] = a[];
return;
} sqr(a, b, (len + ) >> ); for (int i = ; i < len; i++) H[i] = ;
inv(b, H, len); prework(len << );
for (int i = ; i < lim; i++) F[i] = G[i] = ;
for (int i = ; i < len; i++) F[i] = a[i], G[i] = b[i];
ntt(F, ), ntt(G, ), ntt(H, );
for (int i = ; i < lim; i++)
F[i] = (G[i] * G[i] % P + F[i] + P) % P * inv2 % P * H[i] % P;
ntt(F, -); for (int i = ; i < len; i++) b[i] = F[i];
} }; using Poly :: fpow;
using Poly :: P; /* template <typename T>
inline void read(T &X) {
X = 0; char ch = 0; T op = 1;
for (; ch > '9'|| ch < '0'; ch = getchar())
if (ch == '-') op = -1;
for (; ch >= '0' && ch <= '9'; ch = getchar())
X = (X << 3) + (X << 1) + ch - 48;
X *= op;
} */ namespace Fread {
const int L = << ; char buffer[L], *S, *T; inline char Getchar() {
if(S == T) {
T = (S = buffer) + fread(buffer, , L, stdin);
if(S == T) return EOF;
}
return *S++;
} template <class T>
inline void read(T &X) {
char ch; T op = ;
for(ch = Getchar(); ch > '' || ch < ''; ch = Getchar())
if(ch == '-') op = -;
for(X = ; ch >= '' && ch <= ''; ch = Getchar())
X = (X << ) + (X << ) + ch - '';
X *= op;
} } using namespace Fread; namespace Fwrite {
const int L = 2e6 + ; int bufp = ;
char buf[L]; template <typename T>
inline void write(T x) {
if(!x) buf[++bufp] = ''; if(x < ) {
buf[++bufp] = '-';
x = -x;
}
int st[], tp = ;
for(; x; x /= ) st[++tp] = x % ;
for(; tp; tp--) buf[++bufp] = (st[tp] + '');
buf[++bufp] = '\n';
} } using namespace Fwrite; template <typename T>
inline void inc(T &x, T y) {
x += y;
if (x >= P) x -= P;
} template <typename T>
inline void sub(T &x, T y) {
x -= y;
if (x < ) x += P;
} int main() {
/* #ifndef ONLINE_JUDGE
freopen("Sample.txt", "r", stdin);
#endif */ // freopen("3625.in", "r", stdin);
// freopen("3625.out", "w", stdout); read(n), read(m);
for (int x, i = ; i <= n; i++) {
read(x);
if (x <= m) g[x] = ;
} /* for (int i = 0; i <= m; i++)
printf("%lld%c", g[i], " \n"[i == m]); */ g[] = ;
for (int i = ; i <= m; i++) g[i] = (P - 4LL * g[i] % P) % P;
Poly :: sqr(g, f, m + ); /* for (int i = 0; i <= m; i++)
printf("%lld%c", g[i], " \n"[i == m]); for (int i = 0; i <= m; i++)
printf("%lld%c", f[i], " \n"[i == m]); */ inc(f[], 1LL);
for (int i = ; i <= m; i++) g[i] = ;
Poly :: inv(f, g, m + ); /* for (int i = 0; i <= m; i++)
printf("%lld%c", f[i], " \n"[i == m]); */ for (int i = ; i <= m; i++) {
// write(g[i] * 2LL % P);
// printf("\n");
printf("%lld\n", (g[i] + g[i]) % P);
} // fwrite(buf + 1, 1, bufp, stdout);
return ;
}
CF 438E The Child and Binary Tree的更多相关文章
- bzoj 3625(CF 438E)The Child and Binary Tree——多项式开方
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3625 http://codeforces.com/contest/438/problem/E ...
- 【CF】438E. The Child and Binary Tree
http://codeforces.com/contest/438/problem/E 题意:询问每个点权值在 $c_1, c_2, ..., c_m$ 中,总权值和为 $s$ 的二叉树个数.请给出每 ...
- Codeforces 438E The Child and Binary Tree - 生成函数 - 多项式
题目传送门 传送点I 传送点II 传送点III 题目大意 每个点的权值$c\in {c_{1}, c_{2}, \cdots, c_{n}}$,问对于每个$1\leqslant s\leqslant ...
- Codeforces 438E. The Child and Binary Tree 多项式,FFT
原文链接www.cnblogs.com/zhouzhendong/p/CF438E.html 前言 没做过多项式题,来一道入门题试试刀. 题解 设 $a_i$ 表示节点权值和为 $i$ 的二叉树个数, ...
- Codeforces 438E The Child and Binary Tree [DP,生成函数,NTT]
洛谷 Codeforces 思路 看到计数和\(998244353\),可以感觉到这是一个DP+生成函数+NTT的题. 设\(s_i\)表示\(i\)是否在集合中,\(A\)为\(s\)的生成函数,即 ...
- Codeforces 250 E. The Child and Binary Tree [多项式开根 生成函数]
CF Round250 E. The Child and Binary Tree 题意:n种权值集合C, 求点权值和为1...m的二叉树的个数, 形态不同的二叉树不同. 也就是说:不带标号,孩子有序 ...
- 【CF438E】The Child and Binary Tree(多项式运算,生成函数)
[CF438E]The Child and Binary Tree(多项式运算,生成函数) 题面 有一个大小为\(n\)的集合\(S\) 问所有点权都在集合中,并且点权之和分别为\([0,m]\)的二 ...
- [codeforces438E]The Child and Binary Tree
[codeforces438E]The Child and Binary Tree 试题描述 Our child likes computer science very much, especiall ...
- [题解] CF438E The Child and Binary Tree
CF438E The Child and Binary Tree Description 给一个大小为\(n\)的序列\(C\),保证\(C\)中每个元素各不相同,现在你要统计点权全在\(C\)中,且 ...
随机推荐
- ActiveMQ入门之四--ActiveMQ持久化方式
消息持久性对于可靠消息传递来说应该是一种比较好的方法,有了消息持久化,即使发送者和接受者不是同时在线或者消息中心在发送者发送消息后宕机了,在消息中心重新启动后仍然可以将消息发送出去,如果把这种持久化和 ...
- 【POJ】2373 Dividing the Path(单调队列优化dp)
题目 传送门:QWQ 分析 听说是水题,但还是没想出来. $ dp[i] $为$ [1,i] $的需要的喷头数量. 那么$ dp[i]=min(dp[j])+1 $其中$ j<i $ 这是个$ ...
- 浏览器工作原理(三):js运行机制及Event Loop
参考:https://segmentfault.com/a/1190000012925872#articleHeader4 一.为什么有Event Loop Javascript设计之初就是一门单线程 ...
- PHP memcache client封装
config.inc.php $CONFIG_MEMCACHE['default'] = array( //'127.0.0.1:11211:100', '10.9.20.73:11211:100', ...
- 一行命令解决 xcode升级新版本插件失效问题
sudo find ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins -name Info.plist -maxdepth ...
- KindEditor 和 xss过滤
KindEditor 1.进入官网 2.下载 官网下载:http://kindeditor.net/down.php 本地下载:http://files.cnblogs.com/files/wup ...
- Variant
class RTL_DELPHIRETURN Variant: public TVarData Variant转换为字符串 System::Variants::VarToStr VariantArra ...
- bootstrap 自定义
在ror工程内 /app/assets/stylesheets/bootstrap_and_overrides.css.less 内覆盖内容 具体参数如下 https://github.com/twb ...
- 解读linux中用户密码规则及忘记root口令的破解(思路)
linux当中,用户名和密码表对应关系放在/etc/passwd中,如: root:x:0:0:root:/root:/bin/bash 格式代表意义分别为 用户名:密码:用户id:组id:用户描述 ...
- 【译】PGS字幕
PGS(Presentation graphic stream):图形字幕流,是用来显示蓝光电影中的字幕的流.当蓝光盘中的PGS格式的字幕被分离存储的时候通常保存在一个以sup为扩展名的文件中.(也可 ...