「BZOJ 3645」小朋友与二叉树
「BZOJ 3645」小朋友与二叉树
解题思路
令 \(G(x)\) 为关于可选大小集合的生成函数,即
\]
令 \(F(x)\) 第 \(n\) 项的系数为为权值为 \(n\) 的二叉树的方案数,显然有
F^2(x)G(x)-F(x)+1=0 \\
F(x)=\dfrac{1\pm\sqrt{1-4G(x)}}{2G(x)}
\]
当 \(x\to 0\) 时,\(F(x)\) 的值为 \(1\) ,当取加号的时候发现
\]
所以
\]
由于 \(2G(x)\) 的常数项为 \(0\) 不存在逆元,所以要稍作一些变化
=\dfrac{2}{1+\sqrt{1-4G(x)}}
\]
\(\sqrt{1-4G(x)}\) 的常数项为 \(1\) ,一遍开根一遍求逆就好了,复杂度 \(\mathcal O(n\log n)\) ,下面代码拖了多项式板子所以有用不到的部分。
code
/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = (1 << 22) + 5, P = 998244353, G = 3;
namespace poly{
int rev[N], W[N], invW[N], len, lg;
inline int Pow(int a, int b){
int ans = 1;
for(; b; b >>= 1, a = 1ll * a * a % P)
if(b & 1) ans = 1ll * ans * a % P;
return ans;
}
inline void init(){
for(int k = 2; k < N; k <<= 1)
W[k] = Pow(G, (P - 1) / k), invW[k] = Pow(W[k], P - 2);
}
inline void timesinit(int lenth){
for(len = 1, lg = 0; len <= lenth; len <<= 1, lg++);
for(int i = 0; i < len; i++)
rev[i] = (rev[i>>1] >> 1) | ((i & 1) << (lg - 1));
}
inline void DFT(int *a, int sgn){
for(int i = 0; i < len; i++) if(i < rev[i]) swap(a[i], a[rev[i]]);
for(int k = 2; k <= len; k <<= 1){
int w = ~sgn ? W[k] : invW[k];
for(int i = 0; i < len; i += k){
int now = 1;
for(int j = i; j < i + (k >> 1); j++){
int x = a[j], y = 1ll * a[j+(k>>1)] * now % P;
a[j] = (x + y) % P, a[j+(k>>1)] = (x - y + P) % P;
now = 1ll * now * w % P;
}
}
}
if(sgn == -1){
int Inv = Pow(len, P - 2);
for(int i = 0; i < len; i++) a[i] = 1ll * a[i] * Inv % P;
}
}
inline void getinv(int *a, int *b, int n){
static int tmp[N];
if(n == 1) return (void) (b[0] = Pow(a[0], P - 2));
getinv(a, b, (n + 1) / 2);
timesinit(n * 2 - 1);
for(int i = 0; i < len; i++) tmp[i] = i < n ? a[i] : 0;
DFT(tmp, 1), DFT(b, 1);
for(int i = 0; i < len; i++)
b[i] = 1ll * (2 - 1ll * tmp[i] * b[i] % P + P) % P * b[i] % P;
DFT(b, -1);
for(int i = n; i < len; i++) b[i] = 0;
for(int i = 0; i < len; i++) tmp[i] = 0;
}
inline void getsqrt(int *a, int *b, int n){
static int tmp1[N], tmp2[N];
if(n == 1) return (void) (b[0] = 1);
getsqrt(a, b, (n + 1) / 2);
for(int i = 0; i < n; i++) tmp1[i] = a[i];
getinv(b, tmp2, n), timesinit(n * 2 - 1);
DFT(tmp1, 1), DFT(tmp2, 1);
for(int i = 0; i < len; i++) tmp1[i] = 1ll * tmp1[i] * tmp2[i] % P;
DFT(tmp1, -1);
for(int i = 0; i < len; i++)
b[i] = 1ll * (b[i] + tmp1[i]) % P * Pow(2, P - 2) % P;
for(int i = n; i < len; i++) b[i] = 0;
for(int i = 0; i < len; i++) tmp1[i] = tmp2[i] = 0;
}
inline void getln(int *a, int *b, int n){
static int tmp[N];
getinv(a, b, n), timesinit(n * 2 - 1);
for(int i = 1; i < n; i++) tmp[i-1] = 1ll * a[i] * i % P;
DFT(tmp, 1), DFT(b, 1);
for(int i = 0; i < len; i++) b[i] = 1ll * tmp[i] * b[i] % P;
DFT(b, -1);
for(int i = len - 1; i; i--) b[i] = 1ll * b[i-1] * Pow(i, P - 2) % P;
b[0] = 0;
for(int i = n; i < len; i++) b[i] = 0;
for(int i = 0; i < len; i++) tmp[i] = 0;
}
inline void getexp(int *a, int *b, int n){
static int tmp[N];
if(n == 1) return (void) (b[0] = 1);
getexp(a, b, (n + 1) / 2);
getln(b, tmp, n), timesinit(n * 2 - 1);
for(int i = 0; i < n; i++) tmp[i] = (!i - tmp[i] + a[i] + P) % P;
DFT(tmp, 1), DFT(b, 1);
for(int i = 0; i < len; i++) b[i] = 1ll * b[i] * tmp[i] % P;
DFT(b, -1);
for(int i = n; i < len; i++) b[i] = 0;
for(int i = 0; i < len; i++) tmp[i] = 0;
}
inline void power(int *a, int *b, int n, int m, ll k){
static int tmp[N];
for(int i = 0; i < m; i++) b[i] = 0;
int fir = -1;
for(int i = 0; i < n; i++) if(a[i]){ fir = i; break; }
if(fir && k >= m) return;
if(fir == -1 || 1ll * fir * k >= m) return;
for(int i = fir; i < n; i++) b[i-fir] = a[i];
for(int i = 0; i < n - fir; i++)
b[i] = 1ll * b[i] * Pow(a[fir], P - 2) % P;
getln(b, tmp, m);
for(int i = 0; i < m; i++)
b[i] = 1ll * tmp[i] * (k % P) % P, tmp[i] = 0;
getexp(b, tmp, m);
for(int i = m; i >= fir * k; i--)
b[i] = 1ll * tmp[i-fir*k] * Pow(a[fir], k % (P - 1)) % P;
for(int i = 0; i < fir * k; i++) b[i] = 0;
for(int i = 0; i < m; i++) tmp[i] = 0;
}
}
using poly::Pow;
using poly::DFT;
using poly::timesinit;
int a[N], b[N], c[N], n, m;
int main(){
poly::init(), read(n), read(m), m++;
for(int i = 1, x; i <= n; i++)
read(x), a[x] = P - 4;
a[0]++, poly::getsqrt(a, b, m);
b[0] = (b[0] + 1) % P;
poly::getinv(b, c, m);
for(int i = 1; i < m; i++) printf("%lld\n", 2ll * c[i] % P);
return 0;
}
「BZOJ 3645」小朋友与二叉树的更多相关文章
- 「BZOJ 4228」Tibbar的后花园
「BZOJ 4228」Tibbar的后花园 Please contact lydsy2012@163.com! 警告 解题思路 可以证明最终的图中所有点的度数都 \(< 3\) ,且不存在环长是 ...
- 「BZOJ 4502」串
「BZOJ 4502」串 题目描述 兔子们在玩字符串的游戏.首先,它们拿出了一个字符串集合 \(S\),然后它们定义一个字符串为"好"的,当且仅当它可以被分成非空的两段,其中每一段 ...
- 「BZOJ 4289」 PA2012 Tax
「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...
- 「BZOJ 2534」 L - gap字符串
「BZOJ 2534」 L - gap字符串 题目描述 有一种形如 \(uv u\) 形式的字符串,其中 \(u\) 是非空字符串,且 \(v\) 的长度正好为 \(L\), 那么称这个字符串为 \( ...
- 「BZOJ 2956」模积和
「BZOJ 2956」模积和 令 \(l=\min(n,m)\).这个 \(i\neq j\) 非常不优雅,所以我们考虑分开计算,即: \[\begin{aligned} &\sum_{i=1 ...
- Solution -「BZOJ 3812」主旋律
\(\mathcal{Description}\) Link. 给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...
- 「BZOJ 1001」狼抓兔子
题目链接 luogu bzoj \(Solution\) 这个貌似没有什么好讲的吧,直接按照这个给的图建图就好了啊,没有什么脑子,但是几点要注意的: 建双向边啊. 要这么写,中间还要写一个\(whil ...
- 「BZOJ 5188」「Usaco2018 Jan」MooTube
题目链接 luogu bzoj \(Describe\) 有一个\(n\)个节点的树,边有权值,定义两个节点之间的距离为两点之间的路径上的最小边权 给你\(Q\)个询问,问你与点\(v\)的距离大于等 ...
- 「BZOJ 1791」「IOI 2008」Island「基环树」
题意 求基环树森林所有基环树的直径之和 题解 考虑的一个基环树的直径,只会有两种情况,第一种是某个环上结点子树的直径,第二种是从两个环上结点子树内的最深路径,加上环上这两个结点之间的较长路径. 那就找 ...
随机推荐
- [软件]Xcode查找系统framework所在路径
有的时候, 我们不小心改了头文件, 导致Xcode系统库被修改(改回去也不行) 假设我改的是UIKit.framework类库里面的一个文件, 那么你只需要从另一个好使的电脑上, 在这个路径找到UIK ...
- F - Friends ZOJ - 3710(暴力)
题目链接:https://cn.vjudge.net/contest/280949#problem/F 题目大意:给你n个人,然后给你m个关系,每个关系输入t1, t2 .代表t1和t2是朋友关系(双 ...
- python 入门基础4 --数据类型及内置方法
今日目录: 零.解压赋值+for循环 一. 可变/不可变和有序/无序 二.基本数据类型及内置方法 1.整型 int 2.浮点型float 3.字符串类型 4.列表类型 三.后期补充内容 零.解压赋值+ ...
- ZeroMQ安装说明
ZeroMQ安装说明 1. 安装 1.1.Linux zmq安装 安装过程参考地址:http://zeromq.org/intro:get-the-software的说明 安装步骤如下(在安装时参 ...
- Opencv学习笔记——release和debug两个模式的运行问题
本文为原创作品,转载请注明出处 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和http://www.cnblogs.com/xujianqing/ 作者:晨凫 ...
- Linux获取/dev/input目录下的event对应的设备【转】
转自:https://blog.csdn.net/qq_21792169/article/details/51458855 当我们在Linux操作系统下使用input子系统时,当我们先插鼠标,在插上摄 ...
- usb的一些网址
一些关于usb的帖子.网址: usb gadget device g_ether.ko 做成usbnetwork http://bbs.csdn.net/topics/370120345 Linux ...
- MVC 控制器中传递dynamic(对象) 给视图
有时候不想重新定义一个实体,则使用 dynamic 来定义匿名类型. //匿名类型 传递到前台 Model dynamic viewModel = new { UserID = 5016 }; ret ...
- asp.net动态增加服务器端控件并提交表单
为什么要用原生的呢? 1.目的 原生出现浏览器兼容性问题 极少,不用测试多浏览兼容性 .需要考虑到市面上的其他垃圾浏览器. 2.性能不好 如果不考虑第一条 你可以换一种方式 直接上代码 .aspx页面 ...
- 移动端HTML5开发 选择方案
如今出现了大量的CSS前端框架,但真正优秀的框架只有少数几个. 本文将会比较其中五个最佳的框架.每个框架都有自己的优点和缺点,以及具体的应用领域,你可以根据自己的具体项目需求进行选择.此外,许多选项都 ...