退役前的做题记录3

[CERC2017]Gambling Guide

\(f_u\) 表示 \(u\)\(n\) 的期望。
\(f_n=0\)
\[f_u=1+\sum_{v\in suf_v}\frac{min(f_u,f_v)}{d_u}\]
\[\rightarrow f_u=1+\sum_{v\in suf_u,f_v<f_u}\frac{f_v}{d_u}+\sum_{v\in suf_u,f_v\ge f_u}\frac{f_u}{d_u}\]
\[\rightarrow f_u=\sum_{v\in suf_u,f_v<f_u}\frac{f_v+d_u}{\sum_{v\in suf_u,f_v<f_u}1}\]
这个东西满足堆优化 \(Dijkstra\) 的贪心策略,所以就堆优化 \(Dijkstra\) 即可。

TopCoder SRM489Div1:AppleTree

可以先算出满足要求至少要多长,假设长度为 \(L\),那么剩下的 \(d-L\) 可以任意插入,这样就可以直接计算答案了。
考虑怎么算长度,将 \(r\) 从小到大放入,显然后面的一定满足前面的限制。
\(f_{i,j,k}\) 表示插入到了第 \(i\) 个数,有 \(j\) 个空需要插入,总长度为 \(k\) 的方案数。
每次插入一个数字就看插到中间或者两边,可以选择插入之后不计算贡献(表示新建空给后面的插入),如果不新建空就计算长度贡献。

Atcoder ARC071 F:Infinite Sequence

可以发现,如果有连续的两个数字都大于 \(1\),那么后面的数字都是一样的。
\(f_i\) 表示前 \(i\) 个位置的答案(当前位置的数不确定),每次可以写一个 \(1\),或者放一个 \(x(x>1)\)\(x\)\(1\),可以前缀和优化。
每次的 \(f_i\) 贡献答案,可以枚举填两个大于 \(1\) 的,或者填一个大于等于剩下长度的。
注意特判 \(f_i,i=n\) 时候的贡献。

Atcoder AGC013 D:Piling Up

可以发现,如果直接设 \(f_{i,j}\) 表示前 \(i\) 轮,还有 \(j\) 个黑球的方案数,最后的序列会计算重复。
考虑怎么样子才会计算重复,也就是黑球的变化曲线通过上下平移可以重合。
不难同一种方案的曲线中一定会有一条的最小值为 \(0\)
所以强制在最小值为 \(0\) 的时候计算即可。状态里面多加一维 \(0/1\) 表示是否经过 \(0\) 即可。

Atcoder ARC073 F:Many Moves

肯定是两个点交叉走,每次走一个区间。
直接在区间的端点处转移过来,每次贡献为区间长度内的走的代价和另一个点跳过来的代价。
这个显然可以两棵权值线段树维护。

Codeforces 1082 F:Speed Dial

\(trie\) 树上选择 \(k\) 个点即可,简单树形 \(DP\)

Codeforces 1103 D:Professional layer

答案只和 \(d\) 的质因子有关,所以 \(a\) 除掉多余的质数,显然最多选择 \(11\) 个数,每个数字删除 \(d\) 的质因子的一个子集。
那么可以设计出一个简单的状压的子集 \(DP\),然后对于除掉多余的质数相同的肯定选择前 \(11\) 小就好了。
并且一个状态 \(S\),最多只能从小到大转移 \(11\) 次,然后复杂度就卡入 \(20s\) 了,由于非常不满,所以实际上非常的快。

Atcoder ARC073 E:Ball Coloring

分两种情况:
一个是最大值和最小值不在一边,那么直接比较 \(x,y\) 贪心分配即可。
当最大值和最小值在一边的时候,按照 \(x\) 排序,枚举最小值,然后反转前缀的 \(x,y\) 即可。

[ZJOI2012]波浪

只要按照从小到大的顺序插入所有数就行了。
\(f[i][j][k][l]\) 表示插入 \(i\) 个数,当前序列波动值为 \(j\),序列现在被分为 \(k\) 个连续的段,序列边界的状态为 \(l\)\(l\)\(0\) 表示边界没有数,为 \(1\) 表示边界有一个数,为 \(2\) 表示边界有两个数。

Atcoder AGC030 F:Permutation and Minimum

考虑从大到小加入数字,把 \(2n\) 个位置分成 \(n\) 组。
那么可以设计状态 \(f_{i,j,k}\) 表示从大到小的第 \(i\) 个位置,有 \(j\) 个已经知道位置并且有一个未知的个数,\(k\) 个不知道位置并且有一个未知的个数。
然后转移即可,最后乘上两个都未知的个数的阶乘。

Codeforces 809C:Find a car

转化成左上角矩阵的求和,数位 \(DP\),设 \(f_{i,0/1,0/1,0/1}\) 表示 \(i\) 位,三个限制是否到达危险态,记录和和方案数即可。

Codeforces 908G:New Year and Original Order

假设第 \(i\) 位填 \(3\), 那么他的贡献的 \(3\times 10^i\),考虑把这个贡献拆开。
比如:\(3\ge3,3\ge2,3\ge1\) 我们在这一位填 \(1,2,3\) 时都记上 \(10^i\) 的贡献。
\(f_{i,j,k,l}\) 表示前 \(i\) 个位置,有 \(j\) 个位置的数字大于等于 \(k\)\(l\) 表示是否为安全态。
直接转移即可。

Codeforces 799E:Aquarium decoration

按照两个人喜欢的状态分成 \(4\) 类。
首先每一类选的东西肯定是排序之后的一个前缀。
枚举两个都喜欢的选择多少个,贪心选只有一个喜欢的,剩下的选择前 \(k\) 小即可。

TopCoder SRM502Div1:TheCowDivOne

考虑容斥,枚举最后一个数出现的次数 \(i\)
那么可以发现前面 \(k-i\) 个数的取值必须是 \(gcd(n,i)\) 的倍数,不然肯定没有解。
考虑最后这个数的取值有哪一些,当固定前 \(k-i\) 个数的和的时候,最后这个数字显然可以取出 \(gcd(n,i)\) 种值。
\(f_{i,j}\) 表示 \([0,n-1]\) 取出 \(j\) 个,和为 \(i\) 的倍数的方案数。
那么
\[f_{p,k}=\sum_{i=0}^{k}(-1)^{i-1}(n/p)\times gcd(i,p)\times f_{gcd(i,p),k-i}\]
\(n/p\) 表示最后一个数在整个 \([0,n-1]\) 的取值。
注意到我们要选取的集合是无序的,而任何一个数都可以成为最后一个数,那么最后要除掉 \(k\)
考虑这样的状态数,\(f_{i,j}\) 被访问当且仅当 \(i|n,i|(k-j)\)
状态数就是 \(\sum_{i}[i|n]\frac{k}{i}\) 级别的,即 \(kln k\),总复杂度就是 \(O(k^2lnk)\)

POJ1149:PIGS

网络流。
源点向每个猪圈连边,容量为猪的个数。
按照人分层,上一层的点向一层分配,并向汇点连边,容量为每个人的上界。

Codeforces 434D:Nanami's Power Plant

把费用取反之后转化为最小费用的模型,注意到 \(l_i,r_i\) 都很小,很容易可以转化成“HNOI切糕”的模型。
每个点建立 \(r_i-l_i+2\) 个点,相邻两个点 \((x-1,x)\) 之间连边 \(-(a_ix^2+b_ix+c_i)\)
然后对于限制 \((u,v,d)\),就直接 \(u\)\(x\) 号点向 \(v\)\(x-d\) 号点连边 \(inf\) 即可。
最后跑一遍最小割,由于流量不能是负,就给每个点的边加上一个大于所有权值的极大值 \(A\) 即可。
答案就是 \(nA-mincut\)

BZOJ4501:旅行

\(f_u\) 表示 \(u\)\(n\) 的最小期望,\(d_u\) 为出度,\(suf_u\) 为出边集合,那么
\[f_u=1+\frac{\sum_{v\in suf_u}f_v}{d_u}\]
可以选择删掉一些出边,考虑分数规划。
分数规划完之后,由于有删除 \(y\) 就必须删除 \(x\),即选 \(x\) 就必须选 \(y\) 的限制,所以求一个最大权闭合子图即可。

Codeforces 802C:Heidi and Library

费用流。
首先可以拆点,\(i,i+n\)\(-inf\),表示必须选。
对于 \(i,j\) 两天,如果 \(a_i\ne a_j\) 那么连 \(i+n,j\) 边权为 \(c_{a_j}\),否则边权为 \(0\)
这样就只要选出覆盖所有 \(i,i+n\) 的路径,权值和最小就好了。
由于最开始强制了 \(i,i+n\)\(-inf\),所以每一次增广必定覆盖所有 \(i,i+n\) 的路径。
因此根据费用流的性质,只需要当代价不会更小的时候结束增广即可。

[ZJOI2011]营救皮卡丘

费用流。
类似上面的建图,预处理出 \(f_{i,j}\) 表示 \(i\)\(j\) 不经过大于 \(j\) 的点的最短路。
\(i+n\)\(j\)\(f_{i,j}\) 代价的边即可。

TopCoder SRM570Div1:CurvyonRails

费用流。
对于这种网格肯定要想到黑白染色。
考虑如果没有直线的代价怎么求是否有合法方案。
那么就是每个点入度等于出度,由于黑白染色了,所以可以令黑点入流量为 \(2\),白点出流量为 \(2\),相邻的连边网络流出解。
现在有直线的代价,考虑把一个点分出两个点出来,分别表示上下和左右。
选了两次上下或者两次左右的时候有额外代价。
直接连两条边,一条费用 \(0\),一条 \(1\)。因为费用流的性质,所以肯定会先走 \(0\) 边。

BZOJ3691:游行

费用流。
首先可以把额外代价看成是没有入边的点贡献,这样就可以建图,\((i,j+n)\) 费用为最短路。
或者 \((i+n,i)\) 容量为 \(\infty\),只连接原图中有边的 \((i,j+n)\)
现在的问题是多组询问的 \(C\)
根据费用流增广的性质,存在一个增广的时刻,使得之前每次增广的代价小于等于 \(C\),之后大于 \(C\)
那么二分这个分界点就好了。

Codeforces 671D:Roads in Yusland

线性规划问题的对偶问题转化:\(max\{c^Tx|Ax\le b\} = min\{b^Ty|A^Ty\ge c\}\)
放到这个题目转化就变成了:选最多的边(可以重复),使得每个人的覆盖的边不超过 \(c_i\) 条。
这个东西就从深到浅贪心就好了,可并堆维护即可。

CodeChef:Ski Resort

一条路径 \(p_1,p_2,...,p_k\) 不合法当且仅当 \(\exists i < k, p_i < p_{i+1}\)
那么显然可以转化为求 \(S\)\(T\) 的最小割。每个点向小于等于它的点连边即可。
而由于如果同时两个点割了出点同样的边,显然只要增加到两个点的最大值就好了,但是我们割了两次,于是就假了。
所以可以把一个点拆成 \(5\) 个点,把周围的点按照高度小到大排序。
周围的点依次连边这个点拆成的相邻的点,边权为 \(inf\)
这个点相邻的点依次连高度对应的代价。
可以发现,每个点拆成的点如果割掉了后面的边然后再割前面的一定不优,保证了正确性。

Codeforces GYM 101194 J:Mr.Panda and TubeMaster

容易发现是费用流。然后套一个“CTT2017无限之环”发现并不可以,不仅不好限制直线,而且难以处理每个点可以选或不选。
考虑给每一个点钦定一个出边,拆点。
一个比较奇怪的做法就是:先黑白染色,让黑点只考虑上下连边,白点只考虑左右。
这样下来,只需要每个点直接连边就能解决每个点必须选择的问题了。
然后考虑怎么样实现每个点可以选或不选,其实只要自己匹配自己就好了。
最后实际上只要跑一遍二分图最大权匹配就好了。

[CEOI2008]Fence

没想到 111 和 20 居然不是乱给的。。。
首先 \(20\times 3 < 111\) 如果能围住就尽量围住(围住的最小单位显然是 \(3\))。
不能围住的先不管,那么就是对能围住的找到一个最小的环。
枚举每一条向量看是否能围住(都在内侧),然后 \(floyed\) 找最小环即可。

[HAOI2011]防线修建

就是动态删除,要求上凸壳的长度。
倒过来变成动态加入,用平衡树(set)维护凸壳即可。

[SCOI2015]小凸想跑步

求出第一条边和每一条边的限制,这是一个线性规划的形式,半平面交求出可行域即可。

[SDOI2013]逃考

求出泰森多边形,然后连边即可。
枚举每一个点,求出它和每个点的中垂线,这样求出半平面交就可以求出这个点管辖的范围,然后与外面的点连边,最后 \(BFS\) 即可。
Geometry_Widget真好用。

Codeforces 718C:Sasha and Array

矩阵乘法满足结合律,所以就线段树维护矩阵即可。

[FJOI2016]神秘数

考虑从小到大加入数字,假设前面能够凑到 \(x\),如果新的数 \(v \le x+1\),那么能凑出的数变成 \(x+v\),不难发现只要每一次加入 \(\le x+1\) 就好了。主席树维护。
由于每两次一定翻倍,那么就是两只 \(log\)

51NOD 1685:第K大区间2

二分答案,然后询问满足的奇数区间的该个数。

Codeforces 715C:Digit Tree

点分治,因为 \(10^d\)\(m\) 互质,所以存在逆元,\(map\) 查询即可。

Codeforces 833D:Red-Black Cobweb

按照套路,首先点分治。
那么就是要求满足以下条件的路径的权值的乘积。
$\begin{cases}
2(b_1+b_2) \ge w_1+w_2\
2(w_1+w_2) \ge b_1+b_2
\end{cases}
$
由于点是无序的,又不能直接求二次剩余,所以不太好做,直接求可以用 \(CDQ\) 分治解三维偏序,套上点分治,三只 \(log\)
仔细观察这个东西,不合法的条件有两个,但是实际上一个满足,另一个一定不满足,所以求解不合法即可,二维偏序,树形数组实现。

BZOJ4548:小奇的糖果

枚举下边界,向上扫描,每一次删除点。合法的线段一定是相邻两个同色点卡着的,每次合并一下即可。
树形数组+链表维护。

POJ3718:Facer's Chocolate Dream

显然答案只跟 \(1\) 的个数有关,那么可以设 \(f_{i,j}\) 表示选了 \(i\) 个,有 \(j\) 个位置为 \(1\) 的方案数。
因为 \(v\)\(1\) 可以任意组合,我们再除以一个组合数 \(\binom{n}{v}\) 就是答案。
假设选出的 \(m\) 个数不同顺序算是不同的方案,求出来以后再除以一个 \(m!\) 就可以了。
这样就好做了,直接 \(DP\) 即可。四种情况。
但是并没有考虑第 \(i\) 个数与之前的 \(i−1\) 个数重复的情况,所以要减去。
减去的方案数就是 \(f_{i-2,j}\binom{n}{3}(i-1)\)

POJ1845:Sumdiv

按照公式计算即可。注意判断是 \(9901\) 倍数的情况。

牛客Wannafly挑战赛25 A:因子

每个质因子分别考虑即可。

LOJ530:「LibreOJ β Round #5」最小倍数

\(n!\) 中质数 \(k\)\(\sum_{i}\lfloor\frac{n}{k^i}\rfloor\) 个。相当于是将 \(n\) 转化成 \(k\) 进制后,设第 \(i\) 位的值位 \(v\),那么就有 \((v ... . vv)_{k}\) 的贡献。
预处理一下前缀和之类的就可以算出每个 \(k\) 对应的 \(n\),最后取个 \(max\) 就好了。

BZOJ3309:DZY Loves Math

\[\sum_{i=1}^{a}\sum_{j=1}^{b}f(gcd(i,j))=\sum_{d=1}^{min(a,b)}\lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor\sum_{i|d}f(i)\mu(\frac{d}{i})\]
考虑计算 \(g(d)=\sum_{i|d}f(i)\mu(\frac{d}{i})\)
这个东西可以看成是枚举 \(d\) 的质因子集合,钦定这些集合的指数减 \(1\),然后对于所有的指数的 \(max\) 的和。
那么就很好做了。
如果质因子集合的指数都是 \(a\),那么只有一种情况为 \(max=a-1\),其它的情况都是 \(max=a\),这些贡献之间两两抵消,设质因子的个数为 \(k\),那么会剩下一个 \(-(-1)^{k}\)
如果质因子集合的指数不都是 \(a\),那么只有两种情况,一种是 \(max=max\{a\}\),一种是 \(max=max\{a\}-1\),两种情况的方案数都是偶数,同种方案的贡献两两抵消,最后剩下 \(0\)
所以只要求出那些质因子集合的指数相同的数的贡献就好了。
可以发现有值的 \(g\),设为 \(g(x^a)\)(\(a\) 为相同的指数),那么 \(g(x^a)=-\mu(x)\)
所以可以直接枚举 \(\mu\) 筛出 \(g\),复杂度显然是线性的。
用上面的方法配上杜教筛应该是可以做到 \(a,b\le 10^9\) 级别的询问的,枚举那个 \(a\)\(\mu\) 的前缀和就行了(大概)。

BZOJ3561:DZY Loves Math VI

不妨假设 \(n\le m\),爆推:
\[\sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j)^{gcd(i,j)}=\sum_{d=1}^{n}d^{d}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}(ij)^{d}[i\perp j]\]
\[=\sum_{d=1}^{n}d^{d}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}(ij)^{d}\sum_{g|gcd(i,j)}\mu(g)=\sum_{d=1}^{n}d^{d}\sum_{g=1}^{\lfloor\frac{n}{d}\rfloor}\mu(g)\sum_{g|i}^{\lfloor\frac{n}{d}\rfloor}\sum_{g|j}^{\lfloor\frac{m}{d}\rfloor}(ij)^{d}\]
\[=\sum_{d=1}^{n}d^{d}\sum_{g=1}^{\lfloor\frac{n}{d}\rfloor}\mu(g)g^{2d}\sum_{i=1}^{\lfloor\frac{n}{dg}\rfloor}i^d\sum_{j=1}^{\lfloor\frac{m}{dg}\rfloor}j^{d}\]
枚举 \(d\),预处理自然数幂和(显然不用快速幂)暴力计算即可,复杂度为调和级数,\(O(nlnn)\)

BZOJ3601:一个人的数论

爆推:
\[\sum_{i=1}^{n}[i\perp n]i^d=\sum_{i=1}^{n}i^d\sum_{g|gcd(i,n)}\mu(g)=\sum_{g|n}\mu(g)\sum_{g|i}i^d=\sum_{g|n}\mu(g)g^d\sum_{i=1}^{\frac{n}{g}}i^d\]
这玩意儿前面是一个狄利克雷卷积,后面突然出现了一个自然数幂和就很难受。
而众所周知,自然数幂和 \(\sum_{i=1}^{n}i^d\) 是一个关于 \(n\)\(d+1\) 次数多项式。
运用高斯消元或者拉格朗日插值等方法不难得到这个多项式 \(f(x)\),那么答案就可以写成 \(\sum_{g|n}\mu(g)g^df(\frac{n}{d})\)
可以发现,多项式的每一项都是一个 \((\frac{n}{d})^ka_k\)(\(a\) 为系数)的形式,不考虑系数,则这显然是一个积性函数。
因此,只要枚举多项式的幂次,然后对于每一个质因子 \(p_i^{a_i}\) 求出答案即可。

LOJ6102:「2017 山东二轮集训 Day1」第三题

首先有个性质 \(gcd(f_i,f_j)=f_{gcd(i,j)}\)
根据最值反演不难发现有:\[\prod_{T\subset S,T\ne \phi}f(gcd(T))^{(-1)^{|T|+1}}\]
爆推:
\[\prod_{T\subset S,T\ne \phi}f(gcd(T))^{(-1)^{|T|+1}}=\prod_{d=1}^{n}f(d)^{\sum_{T\subset S,T\ne \phi}{(-1)^{|T|+1}}}[gcd(T)=d]\]
\[\sum_{T\subset S,T\ne \phi}{(-1)^{|T|+1}}[gcd(T)=d]=\sum_{d|i}\mu(\frac{i}{d})\sum_{T\subset S,T\ne \phi}{(-1)^{|T|+1}}[i|gcd(T)]\]
\(g_i=\sum_{T\subset S,T\ne \phi}{(-1)^{|T|+1}}[i|gcd(T)]\)
可以发现 \(g_i=\begin{cases}1,\exists k_i,d|k_i\\ 0,otherwise \end{cases}\)
预处理 \(h_d=\sum_{d|i}\mu(\frac{i}{d})g_i\),然后直接计算答案即可。

CodeChef:Counting is life

\(n,k\) 同奇偶的时候,第一问答案显然就是 \(2^{k}-1\),第二问直接构造生成函数,就是 \([x^n](\frac{e^{x}-e^{-x}}{2})^k\),直接二项式定理展开即可。
\(n,k\) 不同奇偶的时候,第一问答案显然就是 \(2^{k}-2\),第二问即 \([x^n](\frac{e^{x}-e^{-x}}{2})^{k-1}(\frac{e^{x}+e^{-x}}{2})\)

CodeChef:Counting D-sets

每一种方案数一定可以平移,使得每一维都有 \(0\),考虑只在每一维都有 \(0\) 的时候计算答案。
显然可以先计算直径至多为 \(d\) 的减去至多为 \(d-1\) 的。
考虑容斥,枚举至多 \(i\) 为没有达到 \(0\),答案即 \(\sum_{i=0}^{n}\binom{n}{i}(-1)^i2^{(d+1)^{n-i}d^i}\)

LOJ6392:「THUPC2018」密码学第三次小作业/Rsa

因为 \(e_1\perp e_2\),所以 \(e_1x+e_2y=1\) 有解。
因为 \(n\perp c_1,n\perp c_2\),所以 \(c_1,c_2\) 有逆元。
解出来 \(x,y\) 之后快速幂即可。

UOJ424:【集训队作业2018】count

\(A=\) 长度为 \(n\) 的序列 \(X\),其中的每个数都是 \(1\)\(m\) 内的整数,且所有 \(1\)\(m\) 内的整数都在序列 \(X\) 中出现过的方案数。
\(B=\) 长度为 \(n\) 的序列 \(X\),其中的每个数都是 \(1\)\(m\) 内的整数,且最大值为 \(m\) 的方案数。
一个结论:当 \(n\ge m\) 的时候,\(A=B\)
为了证明这个东西,首先假设 \(C=\) 长度为 \(n\) 的序列 \(X\),其中的每个数都是 \(1\)\(m\) 内的整数的方案数,然后只要证明 \(A=C\) 并且 \(C=B\) 即可。
首先 \(B=C\),显然对于 \(C\) 的一个方案,把所有的数加上 \(m-max\) 与原来序列同构,就可以得到 \(B\) 了,所以 \(C\le B\),而根据定义显然 \(C\ge B\),所以 \(C=B\)
然后是 \(A=C\),首先根据定义也有 \(C\ge A\),然后对于 \(A\) 的每一种方案,在保证下标前后的大小关系不变的条件下,把相同的数从前往后依次变化(强制后面的小于等于前面的),显然和原来的同构,并且一定可以取遍 \(m\) 个值,所以 \(A\ge C\)
也得到了 \(A=B=C\)
\(B\) 比较好算,设 \(f_{i,j}\) 表示长度为 \(i\),最大值为 \(j\) 的序列的个数。
为了保证同构的不算重复,枚举左右拼接的时候强制在达到最大的情况下计算。
也就是
\[f_{i,j}=\sum_{k=0}^{i-1}f_{k,j-1}f_{i-k-1,j}\]
最后 \(f_{n,m}\) 就是答案。
把数组两维调换 \(f_{i,j}=\sum_{k=0}^{j-1}f_{i-1,k}f_{i,j-k-1}\)
写成多项式 \(f_i=f_if_{i-1}x+1\),那么 \(f_i=\frac{1}{1-f_{i-1}x}\)
不妨假设 \(f_i=\frac{a_i}{b_i}\),那么
\[f_{i+1}=\frac{a_{i+1}}{b_{i+1}}=\frac{1}{1-\frac{a_i}{b_i}x}=\frac{b_i}{b_i-a_ix}\]
写成矩阵的形式
\[(a_i,b_i)\begin{bmatrix}0 & -x \\ 1 & 1 \end{bmatrix}=(a_{i+1},b_{i+1})\]
带入单位根矩阵快速幂,然后 \(IDFT\)\(a,b\),最后求逆即可。
另外的方法

按照题目的大小关系建立这个序列的笛卡尔树,那么左儿子的一定小于当前点,右儿子大小一定小于等于当前点。
不难发现,合法的笛卡尔树必须满足根到每个点向左走的次数必须 \(<m\),这个条件在 \(n\ge m\) 的条件下就是充要条件(根据上面的东西不难得到)。
可以用左儿子右兄弟的方法(新建超级点),多叉树森林转二叉树,同时也可以每次抽出右边的链实现二叉树转多叉树森林,这样子,一个多叉树森林可以一一对应一个二叉树。
至此,题目可以转化成:有多少个长度为 \(2n\) 的合法括号序列,每个前缀(左括号 \(+\),右括号 \(-\) )不超过 \(m\)
也就是 \((0,0)\)\(2n\) 步到 \((n,n)\),每次可以向上走或者向右走 \(1\),使得不超过 \(y=x+m\)\(y=x\) 的路径条数。
算法参见 [JLOI2015]骗我呢。

上面的东西好像有点锅,所以可以去看一看 wxh 的口胡QwQ。

posted @ 2019-03-09 22:54 Cyhlnj 阅读(...) 评论(...) 编辑 收藏