放置于儿童不能接触处的动态规划题目

随机化

题目

为了证明 K n o w N a m e B l o g e r \sf KnowNameBloger KnowNameBloger 常数巨大,邪恶的 H a n d I n D e v i l \sf HandInDevil HandInDevil 与炎翼鸟决定在 grader.exe 里面动一些手脚。

题目输入为一棵树。定义「标枪」为,这个点的点权是这个点到根的链上所有节点的权值最大值。形式化的,点 x x x 是「标枪」当且仅当 ∀ y ∈ p a t h ( x , r o o t ) ,    v y < v x \forall y\in{\rm path}(x,root),\;v_y<v_x ypath(x,root),vy<vx 。如果有 c c c 个「标枪」点,那么 K n o w N a m e B l o g e r \sf KnowNameBloger KnowNameBloger 的代码运行速度会变成原来的 k c k^c kc 倍( k k k A r e x t r e \sf Arextre Arextre 设定的常数)。

然后 i C u \sf iCu iCu 用随机排列给树分配了点权。我们已经看到 K n o w N a m e B l o g e r \sf KnowNameBloger KnowNameBloger 的代码跑了 1 0 1 0 10 10^{10^{10}} 101010 秒,我们只需要求出,她的代码运行速度的倍数加成(即 k c k^c kc)的期望。由于她的代码常数实在太大,你只需要输出 k c k^c kc 的期望值乘 n ! n! n! 再取模 998244353 998244353 998244353 后的结果。

思路

先考虑一个暴力。称「标枪」为黑点,非「标枪」为白点,先 2 n 2^n 2n 枚举颜色,然后每个点似乎就有 d e p t h depth depth 个点权大小关系限制?

事实上,黑点的白点祖先必然小于它,因为白点 < < < < < < 黑点。还有,一条链上的 k k k 个黑点是一个连不等号的关系,即最深的 > > > 次深的 > > > ⋯ \cdots > > > 最浅的(即根节点)。这是黑点的情况,白点也是类似的。所以最终 精简为了只有两种限制

  1. 白点的点权 < < < 第一个黑点祖先的点权。
  2. 黑点的点权 > > > 第一个黑点祖先的点权。

如果点权大的向点权小的连边,这就会形成一个 树形结构,因为每个点只连出一条边(而根节点无出边)。这个东西大家都会,随意选择一个点当作根,然后 容斥向下的边,一部分钦定为向上,容斥系数为 − 1 -1 1 的这种边的数量次方,剩余的向下边砍掉。向上的边,就是每个点必须是子树内最小值,经典问题了,直接 ∏ 1 s i z e \prod{1\over size} size1 就行。

在本题中,就指定原树的树根为新树的树根。现在就可以设计 d p \tt dp dp 状态了。设 f ( i , j ) f(i,j) f(i,j) 表示,以 i i i 为根的子树中,总共向上连的点有 j j j 个(即,需要获得父节点的所有树的大小之和),方案数(含容斥系数)之和。这里的概率为点权是 1 1 1 s i z e i size_i sizei 的排列的情况。考虑转移。

一个巧妙之处是,不同子树的 期望值可以直接相乘。因为 p ( a ) ⋅ k a ⋅ p ( b ) ⋅ k b = p ( a + b ) ⋅ k a + b p(a)\cdot k^a\cdot p(b)\cdot k^b=p(a+b)\cdot k^{a+b} p(a)kap(b)kb=p(a+b)ka+b 。所以子树内有 j j j 条向上的边的方案数之和 g ( j ) g(j) g(j) 就是子树的 f f f 的卷积。

  1. 如果是白点:若它是断开了边的那一类,那么上下是独立的,期望的可加性得 f ( i , j ) += ⁡ g ( j ) f(i,j)\operatorname{+=}g(j) f(i,j)+=g(j) 。若它是改成向上边的一类,由于白点在新树上没有子节点,所以 1 s i z e 1\over size size1 就是 1 1 1,即 f ( i , j + 1 ) − = g ( j ) f(i,j+1){-\text=}g(j) f(i,j+1)=g(j)
  2. 如果是黑点:所有子树内的黑点都得连向他。别忘了计算概率。即 f ( i , j + 1 ) += ⁡ k ⋅ g ( j ) j + 1 f(i,j+1)\operatorname{+=}{k\cdot g(j)\over j+1} f(i,j+1)+=j+1kg(j)

然后就 O ( n 2 ) \mathcal O(n^2) O(n2) 做完了。

三元组

题目

一棵 n    ( n ⩽ 1 0 6 ) n\;(n\leqslant 10^6) n(n106) 个点的树,记 d i s ( u , v ) dis(u,v) dis(u,v) 为树上 u , v u,v u,v 最短距离的长度(边的长度均为 1 1 1),请计算满足下面条件的有序三元组 ⟨ A , B , C ⟩ \langle A,B,C\rangle A,B,C 的个数:
∣ { A , B , C } ∣ = 3 ,    d i s ( A , B ) ≤ max ⁡ [ d i s ( A , C ) , d i s ( B , C ) ] \big|\{A,B,C\}\big|=3,\;dis(A,B)\le\max[dis(A,C),dis(B,C)] {A,B,C} =3,dis(A,B)max[dis(A,C),dis(B,C)]

思路

看上去很恐怖,但是仔细想一想,这东西是个 轮换式。这说明,对于任意的 A , B , C A,B,C A,B,C,把它们重新排列后就会计数特定次数。比如此处,欲求 c ≤ max ⁡ ( b , a ) c\le\max(b,a) cmax(b,a) 的数量,不妨设 c < b < a c<b<a c<b<a,那么可行的排列就是
⟨ c , b , a ⟩ , ⟨ c , a , b ⟩ , ⟨ b , c , a ⟩ , ⟨ b , a , c ⟩ \langle c,b,a\rangle,\langle c,a,b\rangle,\langle b,c,a\rangle,\langle b,a,c\rangle c,b,a,c,a,b,b,c,a,b,a,c

但是有些特殊情况。如果 c ≤ b = a c\le b=a cb=a,那么可行的排列有全部六种。所以,我们只需要考虑这种特殊情况,即 最大值与次大值相等

这种情况会长什么样子呢?不难发现,一定可以找到一个点 x x x 使得 x x x A , B , C A,B,C A,B,C 三者的路径不相交。(因为 x x x 就是 l c a ( A , B ) , l c a ( B , C ) , l c a ( A , C ) lca(A,B),lca(B,C),lca(A,C) lca(A,B),lca(B,C),lca(A,C) 三者中最深的那个。)如果三条路径长度分别为 a , b , c a,b,c a,b,c,不妨设 a ≤ b ≤ c a\le b\le c abc,那么最大值为 b + c b+c b+c,次大值为 a + c a+c a+c,二者要相等,所以 a = b a=b a=b

那么考虑 枚举 “中心点”。如果最短的两条都在子树内,就是子树内选等深、子树外选足够长。如果最长的一条在子树内,就是子树内选不等深,子树外选较短深度者。

  • f ( x , i ) f(x,i) f(x,i) 为,使得 l c a ( u , v ) = x lca(u,v)=x lca(u,v)=x d i s ( u , x ) > d i s ( v , x ) = i dis(u,x)>dis(v,x)=i dis(u,x)>dis(v,x)=i 的无序二元组 ⟨ u , v ⟩ \langle u,v\rangle u,v 的数量。
  • g ( x , i ) g(x,i) g(x,i) 为,使得 l c a ( u , v ) = x lca(u,v)=x lca(u,v)=x d i s ( u , x ) = d i s ( v , x ) = i dis(u,x)=dis(v,x)=i dis(u,x)=dis(v,x)=i 的无序二元组 ⟨ u , v ⟩ \langle u,v\rangle u,v 的数量。
  • h ( x , i ) h(x,i) h(x,i) 为,使得 l c a ( x , u ) ≠ x lca(x,u)\ne x lca(x,u)=x(即 u u u 在子树外)且 d i s ( x , u ) ≤ i dis(x,u)\le i dis(x,u)i u u u 的数量。

此时 x x x 对答案的贡献就可以求了。

  • 最短的两条在子树内,内部选择 g ( x , i ) g(x,i) g(x,i),外部选择 h ( x , i − 1 ) h(x,i-1) h(x,i1) 以外的点。
  • 最长的一条在子树内,内部选择 f ( x , i ) f(x,i) f(x,i),外部选择 h ( x , i ) − h ( x , i − 1 ) h(x,i)-h(x,i-1) h(x,i)h(x,i1)

然后问题转化为,怎么求 f , g , h f,g,h f,g,h 三个值。你要先观察到 i i i 的范围:因为 g ( x , i ) g(x,i) g(x,i) 要选两个,所以 i i i 的范围是 短链长度(“短链” 即次长链),毕竟长链上只能选一个。同理可知 f ( x , i ) f(x,i) f(x,i) i i i 的范围是短链长度。

于是乎,我们可以用经典长链剖分求出 p ( x , i ) p(x,i) p(x,i) x x x 的子树内、到 x x x 的距离为 i i i 的点的数量,然后 暴力计算 f f f g g g(就是先硬算,然后减去儿子节点以保证 l c a = x lca=x lca=x 成立)。

然而 h h h 怎么求呢?先试着写一写递推式吧。
h ( x , i ) = h ( f a , i − 1 ) + ∑ j = 0 i − 1 p ( f a , j ) − ∑ j = 0 i − 2 p ( x , j ) h(x,i)=h({\rm fa},i-1)+\sum_{j=0}^{i-1} p({\rm fa},j)-\sum_{j=0}^{i-2}p(x,j) h(x,i)=h(fa,i1)+j=0i1p(fa,j)j=0i2p(x,j)

再想想,我们询问的 h ( x , i ) h(x,i) h(x,i) i i i 不超过短链长度(由 f , g f,g f,g 的 “局限性” 导致),我们不妨慷慨一点,改成 长链长度,那么 h ( f a , i − 1 ) h({\rm fa},i-1) h(fa,i1) 中的 i − 1 i-1 i1 的范围是 x x x 的长链长度 − 1 -1 1 。众所周知 f a {\rm fa} fa 的长链长度至少是 x x x 的长链长度 + 1 +1 +1,所以够用。

再一看,这又是长链剖分经典式子。当 x x x f a \rm fa fa 在同一长链上时,若 i i i 超过 f a \rm fa fa 的短链长度,那后面这两个 ∑ \sum 的差值就不再变化了,可以打 整体加的懒标记,前缀减去此标记来修正。这个差值最好是先用另一个数组存储(因为它的含义就是 f a \rm fa fa 去掉 x x x 的子树之后的 p p p 值)。

x x x f a \rm fa fa 不在同一长链上时,可以 O ( \mathcal O( O( x x x 的长链长度 ) ) ) 暴力计算。当然,由于这里用到了 p p p,所以必须要用 可回退数据结构 维护 p p p,才能在自顶向下的 h h h 计算中得到正确的 p p p 值。这东西听上去恐怖,其实就是 “时光倒流”,把加上去的短链的贡献减掉即可。

那么整道题就做完了。时间复杂度 O ( n ) \mathcal O(n) O(n),但是常数巨大。

长( c h a ˊ n g cháng chaˊng)者

题目

一个长度为 n ( n ⩽ 1 0 5 ) n(n\leqslant 10^5) n(n105) 的排列,有些位置上的数字已经确定了,剩下位置上的数字不确定。你要确定剩下位置上的数字,让得到的排列的最长上升子序列长度尽量长。

思路

回想一般的 L I S \tt LIS LIS 做法。常见的做法是 g ( x ) g(x) g(x) 表示以 x x x 作为结尾的值,最长的 L I S \tt LIS LIS 。其实,本质就是 f ( i ) f(i) f(i) 的转移条件为 p j < p i ∧ j < i p_j<p_i\wedge j<i pj<pij<i,用枚举顺序去掉了第二维,利用单调性将树状数组改成了二分罢了。

在这里我们当然还可以设 f ( i ) f(i) f(i) 为以 i i i 结尾的最长 L I S \tt LIS LIS 。如果 p i p_i pi 是未知的,怎么转移呢?当然是让 p i p_i pi 尽量小啊!如果后面有人又是从 i i i 转移的,也就跟着设置为尽可能小。直到出现已知的 p i p_i pi 。也就是说,中间的转移都只是为了已知的 p i p_i pi 作铺垫。

那我们干脆要求 p i p_i pi 是已知的。枚举上一个确定的位置 j ( j < i ) j(j<i) j(j<i) 则有
f ( i ) = max ⁡ p j < p i { f ( j ) + min ⁡ ( c i − c j , r i − r j ) } + 1 f(i)=\max_{p_j<p_i}\big\{f(j)+\min(c_i-c_j,r_i-r_j)\big\}+1 f(i)=pj<pimax{f(j)+min(cicj,rirj)}+1

其中 c i c_i ci 为下标 [ 1 , i ] [1,i] [1,i] 中有多少个位置不确定。即 c i − c j c_i-c_j cicj 为下标 ( j , i ] (j,i] (j,i] 中空缺的 p p p 。而 r i r_i ri 表示 [ 1 , i ] [1,i] [1,i] 中有多少个 p p p 未使用。即 r i − r j r_i-r_j rirj 表示,对于所有 p ∈ ( j , i ] p\in(j,i] p(j,i],有多少个 p p p 没出现过。

式子写出来了,发现是 O ( n 2 ) \mathcal O(n^2) O(n2) 的。可笑!优化方法不都写在第一自然段吗?这种问题也能难倒我们?唯一特别的不过是这个 min ⁡ { c i − c j ,    r i − r j } \min\{c_i{-}c_j,\;r_i{-}r_j\} min{cicj,rirj} 罢了。讨论一下 ( c i − r i ) (c_i{-}r_i) (ciri) ( c j − r j ) (c_j{-}r_j) (cjrj) 的值,很容易就能确定选择的是哪一项。

然后问题变成了 三维偏序,即 j < i ,    p j < p i ,    c j − r j < c i − r i j<i,\;p_j<p_i,\;c_j-r_j<c_i-r_i j<i,pj<pi,cjrj<ciri 。最外层 c d q \tt cdq cdq 分治,内部 t w o    p o i n t e r s \rm two\;pointers twopointers 的时候用 B I T \tt BIT BIT 辅助一下。复杂度 O ( n log ⁡ 2 n ) \mathcal O(n\log^2n) O(nlog2n)

多项式挑战

题目

有一棵无穷大的完全二叉树 T T T,任意一个点都有两个子节点。

给定一棵有限的二叉树 G G G,满足除叶节点外每个节点都有恰好两个儿子,你需要把 G G G 嵌入 T T T 中。具体而言,你需要找一个单射 f : G ↦ T f:G\mapsto T f:GT 满足:

  1. 对于 G G G 中的每个非叶节点 u u u,设其两个子节点分别为 l , r l,r l,r,则 f ( l ) f(l) f(l) f ( u ) f(u) f(u) 的左子树中,且 f ( r ) f(r) f(r) f ( u ) f(u) f(u) 的右子树中。
  2. 对于 G G G 中的每个叶节点 v v v f ( v ) f(v) f(v) 的深度必须恰好为 h v h_v hv,其中一个点的深度是它到根节点所需要经过的边数。 h h h 是一个给定的数组。

你需要求方案数对 1 0 9 + 7 10^9+7 109+7 取模的结果。两个方案不同,当且仅当存在一个点 u u u 使得 f ( u ) f(u) f(u) 在两个方案中不同。

数据范围较小, n ≤ 5 × 1 0 3 n\le 5\times 10^3 n5×103 h i ≤ 1 0 9 h_i\le 10^9 hi109 。同时也请注意, f ( 1 ) f(1) f(1) 不一定需要是 T T T 的根节点;可能有无解的情况。

思路

考虑朴素的 d p \tt dp dp,用 g ( i , j ) g(i,j) g(i,j) 表示 f ( i ) f(i) f(i) 的深度至少为 j j j 时,子树内的答案。那么
g ( i , j ) = ∑ x = j + ∞ 2 x − j ⋅ g ( l , x + 1 ) ⋅ g ( r , x + 1 ) g(i,j)=\sum_{x=j}^{+\infty}2^{x-j}\cdot g(l,x{+}1)\cdot g(r,x{+}1) g(i,j)=x=j+2xjg(l,x+1)g(r,x+1)

如果再加一个后缀和优化,即
g ( i , j ) = 2 ⋅ g ( i , j + 1 ) + g ( l , j + 1 ) ⋅ g ( r , j + 1 ) g(i,j)=2\cdot g(i,j\text+1)+g(l,j\text+1)\cdot g(r,j\text+1) g(i,j)=2g(i,j+1)+g(l,j+1)g(r,j+1)

就获得了一个 O ( h ⋅ n ) \mathcal O(h\cdot n) O(hn) 的优秀算法。

按照这个方向走,就会 进入死胡同 了。思路明明差不多,但是朝着这个方向推,就会颗粒无收。这究竟是为什么啊?

我们不得不更改定义。设 d ( i , j ) = g ( i , j ) − 2 g ( i , j + 1 ) d(i,j)=g(i,j)-2g(i,j{+}1) d(i,j)=g(i,j)2g(i,j+1),即 f ( i ) f(i) f(i) 深度恰好为 j j j 的答案。那么有转移
d ( i , j ) = ( ∑ x > j d ( l , x ) 2 x − j − 1 ) ( ∑ x > j d ( r , x ) 2 x − j − 1 ) d(i,j)= \left(\sum_{x>j}d(l,x)2^{x-j-1}\right) \left(\sum_{x>j}d(r,x)2^{x-j-1}\right) d(i,j)=(x>jd(l,x)2xj1)(x>jd(r,x)2xj1)

为了 尽可能将 x x x j j j 撇清关系,不再用原有的 g ( i , j ) = ∑ x ⩾ j d ( i , x ) g(i,j)=\sum_{x\geqslant j}d(i,x) g(i,j)=xjd(i,x) 而是
g ( i , j ) = ∑ x > j 2 x ⋅ d ( i , x ) g(i,j)=\sum_{x>j}2^{x}\cdot d(i,x) g(i,j)=x>j2xd(i,x)

那么
d ( i , j ) = 2 − 2 j − 2 ⋅ g ( l , j ) ⋅ g ( r , j ) d(i,j)=2^{-2j-2}\cdot g(l,j)\cdot g(r,j) d(i,j)=22j2g(l,j)g(r,j)

而后 不难发现 仍然可以用多项式去拟合 g ( i , j ) g(i,j) g(i,j) 。不过肯定不是 j j j 的幂级数。因为你可以大概写出
g ( i , j ) = ∑ x > j 2 x ⋅ d ( i , x ) = ∑ x > j 2 x ⋅ 2 − 2 x − 2 ⋅ g ( l , x ) ⋅ g ( r , x ) \begin{aligned} g(i,j)&=\sum_{x>j}2^{x}\cdot d(i,x)\\ &=\sum_{x>j}2^{x}\cdot 2^{-2x-2}\cdot g(l,x)\cdot g(r,x) \end{aligned} g(i,j)=x>j2xd(i,x)=x>j2x22x2g(l,x)g(r,x)

然后 不难发现 这是 关于 2 − j 2^{-j} 2j 的幂级数。形式化地说,存在一个 G i ( x ) = ∑ j = 0 k i a i j x j G_i(x)=\sum_{j=0}^{k_i}a_{ij}x^j Gi(x)=j=0kiaijxj 使得
g ( i , j ) = G i ( 2 − j ) g(i,j)=G_i(2^{-j}) g(i,j)=Gi(2j)

这是因为
G i ( 2 − j ) = ∑ x > j 2 − x − 2 ⋅ G l ( 2 − x ) ⋅ G r ( 2 − x ) G_i(2^{-j})=\sum_{x>j}2^{-x-2}\cdot G_l(2^{-x})\cdot G_r(2^{-x}) Gi(2j)=x>j2x2Gl(2x)Gr(2x)

如果记 B ( x ) = G l ( x ) ⋅ G r ( x ) = ∑ i = 0 k l + k r b i x i B(x)=G_l(x)\cdot G_r(x)=\sum_{i=0}^{k_l+k_r}b_ix^i B(x)=Gl(x)Gr(x)=i=0kl+krbixi
G i ( 2 − j ) = ∑ x > j 2 − x − 2 ∑ t = 0 k l + k r b t ( 2 − x ) t = ∑ t = 0 k l + k r b t ∑ x > j 2 − x − 2 × 2 − x t = 1 4 ∑ t = 0 k l + k r b t ∑ x > j 2 − x ( t + 1 ) = 1 4 ∑ t = 0 k l + k r b t ⋅ 2 − j ( t + 1 ) − 2 − h ( t + 1 ) 2 t + 1 − 1 \begin{aligned} G_i(2^{-j})&=\sum_{x>j}2^{-x-2}\sum_{t=0}^{k_l+k_r}b_t(2^{-x})^t\\ &=\sum_{t=0}^{k_l+k_r}b_t\sum_{x>j}2^{-x-2}\times 2^{-xt}\\ &={1\over 4}\sum_{t=0}^{k_l+k_r}b_t\sum_{x>j}2^{-x(t+1)}\\ &={1\over 4}\sum_{t=0}^{k_l+k_r}b_t\cdot {2^{-j(t+1)}-2^{-h(t+1)}\over 2^{t+1}-1} \end{aligned} Gi(2j)=x>j2x2t=0kl+krbt(2x)t=t=0kl+krbtx>j2x2×2xt=41t=0kl+krbtx>j2x(t+1)=41t=0kl+krbt2t+112j(t+1)2h(t+1)

所以
G i ( x ) = 1 4 ∑ t = 0 k l + k r b t 2 t + 1 − 1 ⋅ ( x t + 1 − 2 − h ( t + 1 ) ) G_i(x)={1\over 4}\sum_{t=0}^{k_l+k_r}{b_t\over 2^{t+1}-1} \cdot(x^{t+1}-2^{-h(t+1)}) Gi(x)=41t=0kl+kr2t+11bt(xt+12h(t+1))

显然仍然是多项式。只剩下一个问题了, k i = k l + k r + 1 k_i=k_l+k_r+1 ki=kl+kr+1 的范围是什么呢?答案是子树内的点数减叶子数。因为对于叶子节点 u u u g ( u , j ) = 2 h u    ( j < h u ) g(u,j)=2^{h_u}\;(j<h_u) g(u,j)=2hu(j<hu) 是零次的。

卷积可以暴力做,因为每一对点在 l c a lca lca 提供 O ( 1 ) \mathcal O(1) O(1) 的复杂度,总复杂度 O ( n 2 ) \mathcal O(n^2) O(n2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值