NOIP 2024 解题分析
1.编辑字符串
题意:有两个长为 n n n 的 0 / 1 0/1 0/1 字符串,字符串的有些位置可以进行邻项交换,有的位置不可以。可以进行多次交换。问:多次交换后,相同位置字符相同的位置最多有多少。多组数据。 1 ≤ T ≤ 10 , 1 ≤ n ≤ 1 0 5 1 \le T \le 10, 1 \le n \le 10^5 1≤T≤10,1≤n≤105。
分析:可以进行前后交换,不好动归。可以交换的部分构成一个连续段,该连续段的字符可以看成可任意位置交换。有一个明显的贪心思路:如果 s 1 s_1 s1 的某个位置和 s 2 s_2 s2 的某个位置能够匹配,让他们匹配,如果不匹配,该位置即使交换到后面去,最多也是匹配一次,答案不会更优。
以样例为例,红色框里是可以交换的连续段,绿色框不能交换,则可以看作只包含单个元素的段。这样形式就能统一。对于每个框统计里面有多少个 0 0 0 和多少个 1 1 1。指针 i i i 指向第一个字符串的首位置,指针 j j j 指向第二个字符串的首位置。先看能不能匹配 0 0 0,如果能则匹配,继续下一个位置,同时两个段的 0 0 0 的数量减去 1 1 1,如果不能匹配 0 0 0,则看能不能匹配 1 1 1。如果哪个连续段的数字匹配完毕,则继续进行该字符串的下一个连续段。时间复杂度 O ( n ) O(n) O(n)。
2.遗失的赋值
题意:有 n n n 个变量 x 1 … n x_{1\dots n} x1…n 没有赋值,它的取值范围是 [ 1 , v ] [1,v] [1,v]。对这 n n n 个变量有两种限制,一种是指定 m m m 个位置的值,即这些位置的值是确定的。另一种是二元组限制 ( a i , b i ) ( 1 ≤ i ≤ n − 1 ) (a_i,b_i)(1 \le i \le n-1) (ai,bi)(1≤i≤n−1),如果 x i x_i xi 赋值为 a i a_i ai,则 x i + 1 x_{i+1} xi+1 必须赋值为 b i b_i bi。如果 x i x_i xi 没有赋值为 a i a_i ai,则 x i + 1 x_{i+1} xi+1 没有限制。 a i , b i a_i,b_i ai,bi 取值范围是 [ 1 , v ] [1,v] [1,v]。问:有多少种 a i , b i a_i,b_i ai,bi 的取值方案,能让 x 1 … n x_{1 \dots n} x1…n 存在至少一种赋值方案,取值方案取模。 1 ≤ T ≤ 10 , 1 ≤ n ≤ 1 0 9 , 1 ≤ m ≤ 1 0 5 , 2 ≤ v ≤ 1 0 9 1 \le T \le 10, 1 \le n \le 10^9,1 \le m \le 10^5,2 \le v \le 10^9 1≤T≤10,1≤n≤109,1≤m≤105,2≤v≤109。
分析:对于 x i − 1 , x i x_{i-1},x_i xi−1,xi 来说,如果 x i − 1 = a i − 1 x_{i-1} = a_{i-1} xi−1=ai−1,则 x i x_i xi 的值就是确定的为 b i − 1 b_{i-1} bi−1,否则, x i x_i xi 的值就是不确定的,可以取任意值。 x i x_i xi 的值分为确定的和不确定的两种。 f [ i ] [ 0 / 1 ] f[i][0/1] f[i][0/1] 表示规划到第 i i i 个位置, 0 0 0 是第 i i i 个位置的值是不确定的, 1 1 1 表示第 i i i 个位置的值是确定的,此时的赋值方案数。
特殊情况:如果一元限制有冲突,即第 i i i 个位置规定是 v 1 v1 v1,同时又规定是 v 2 v2 v2,则答案为 0 0 0。
如果第
i
i
i 个位置本身有一元限制,则这个位置只能是确定的:
f
[
i
]
[
1
]
=
v
2
×
f
[
i
−
1
]
[
0
]
+
(
(
v
−
1
)
×
v
+
1
)
×
f
[
i
−
1
]
[
1
]
f
[
i
]
[
0
]
=
0
f[i][1] = v^2 \times f[i-1][0] + ((v-1) \times v + 1) \times f[i-1][1] \\ f[i][0]=0
f[i][1]=v2×f[i−1][0]+((v−1)×v+1)×f[i−1][1]f[i][0]=0
方程解释:第
i
−
1
i-1
i−1 个位置不确定的话,
(
a
i
−
1
,
b
i
−
1
)
(a_{i-1},b_{i-1})
(ai−1,bi−1) 可以任意取,为
v
2
v^2
v2。第
i
−
1
i-1
i−1 个位置如果确定的话,如果
a
i
−
1
a_{i-1}
ai−1 等于
x
i
−
1
x_{i-1}
xi−1 这个确定的值的话,
b
i
−
1
b_{i-1}
bi−1 只能等于
a
i
a_i
ai 这个确定的值,有
1
1
1 种;如果
a
i
−
1
a_{i-1}
ai−1 不等于
x
i
−
1
x_{i-1}
xi−1 这个确定的值,
(
a
i
−
1
,
b
i
−
1
)
(a_{i-1},b_{i-1})
(ai−1,bi−1) 有
v
×
(
v
−
1
)
v \times (v-1)
v×(v−1) 种。
如果第
i
i
i 个位置本身没有一元限制,则这个位置可以是确定的,也可以是不确定的。
f
[
i
]
[
1
]
=
v
×
f
[
i
−
1
]
[
1
]
f
[
i
]
[
0
]
=
v
2
×
f
[
i
−
1
]
[
0
]
+
(
(
v
−
1
)
×
v
)
×
f
[
i
−
1
]
[
1
]
f[i][1]= v \times f[i-1][1] \\ f[i][0] = v^2 \times f[i-1][0] + ((v-1) \times v ) \times f[i-1][1]
f[i][1]=v×f[i−1][1]f[i][0]=v2×f[i−1][0]+((v−1)×v)×f[i−1][1]
方程解释:第
i
i
i 个位置是确定的值的话,意味着第
i
−
1
i-1
i−1 位置的也是确定的值,而且满足
a
i
−
1
=
=
x
i
−
1
a_{i-1} == x_{i-1}
ai−1==xi−1,此时对于任意的
b
i
−
1
b_{i-1}
bi−1,
x
i
x_i
xi 的值和
b
i
−
1
b_{i-1}
bi−1 相等,有
v
×
f
[
i
−
1
]
[
1
]
v \times f[i-1][1]
v×f[i−1][1] 种。第
i
i
i 个位置是不确定的值的话,如果第
i
−
1
i-1
i−1 位置是不确定值,则
a
i
−
1
,
b
i
−
1
a_{i-1},b_{i-1}
ai−1,bi−1 取值任意,为
v
2
v^2
v2,如果第
i
−
1
i-1
i−1 位置是确定值,那么
a
i
−
1
a_{i-1}
ai−1 就不能等于
x
i
−
1
x_{i-1}
xi−1,一旦相等则
x
i
x_i
xi 的值也变成确定的了,此时
x
i
−
1
x_{i-1}
xi−1 有
v
−
1
v-1
v−1 种取值,
x
i
x_i
xi 有
v
v
v 种取值,方案为
(
v
−
1
)
×
v
(v-1) \times v
(v−1)×v。
以上时间复杂度是 O ( n ) O(n) O(n) 的,可以用矩阵快速幂加速。怎么设计方阵?有的位置有一元限制,有的位置没有。对于每个一元限制的位置,用矩阵快速幂快速求出 f [ i ] [ 0 / 1 ] f[i][0/1] f[i][0/1],直到最后一个一元限制的位置。
(1)
n
n
n 的取值范围大,
m
m
m 的取值范围小,需要从
m
m
m 考虑。对于两个有一元限制的位置假如是
p
1
,
p
2
p_1,p_2
p1,p2,则
[
p
1
,
p
2
]
[p_1,p_2]
[p1,p2] 构成一段独立的区间,该段区间的两头是固定值。那么整个
n
n
n 的序列,总共构成
m
−
1
m-1
m−1 段这样的独立区间,外加一头开放、另外一头有固定值的首尾两段区间。分别计算出每一段的方案数,然后根据乘法原理,就能计算出答案。现在单独考虑某一段这样的区间。
如上图,
1
,
6
1,6
1,6 位置有一元限制,整个区间长度为
6
6
6,二元限制的个数是
5
5
5。设
f
[
x
]
f[x]
f[x] 表示有
x
x
x 个二元限制的方案数。对于最左边的位置
1
1
1,如果此时的
a
1
a_1
a1 值和该位置的一元限制的值相同,那么
b
1
b_1
b1 的值就等于第二个位置的值,有
v
v
v 种情况,此时第二个位置的值也是固定的值,规模缩小,为
v
×
f
[
x
−
1
]
v \times f[x-1]
v×f[x−1]。 否则,即此时的
a
1
a_1
a1 值和该位置的一元限制的值不同,第二个位置的值可以随便取,因为
v
>
2
v>2
v>2,所以
b
1
b_1
b1 肯定可以和第二个位置的值取得不一样,第三个位置的值也可以随便取了,后面以此类推,有
x
−
1
x-1
x−1 组二元限制,方案为
(
v
2
)
x
−
1
(v^2)^{x-1}
(v2)x−1,再加上
(
a
1
,
b
1
)
(a_1,b_1)
(a1,b1) 的取值,共
(
v
−
1
)
×
v
×
(
v
2
)
x
−
1
(v-1) \times v \times (v^2)^{x-1}
(v−1)×v×(v2)x−1。因此:
f
[
x
]
=
v
×
f
[
x
−
1
]
+
(
v
−
1
)
×
v
×
v
2
x
−
2
f[x] = v \times f[x-1] + (v-1) \times v \times v^{2x-2}
f[x]=v×f[x−1]+(v−1)×v×v2x−2
x
x
x 的上限可能达到
1
0
9
10^9
109,直接递推也不行。考虑化简:
f
[
x
]
=
v
2
x
−
v
2
x
−
1
+
v
×
f
[
x
−
1
]
v
×
f
[
x
−
1
]
=
v
×
(
v
2
x
−
2
−
v
2
x
−
3
+
v
×
f
[
x
−
2
]
)
f
[
x
]
=
v
2
x
−
v
2
x
−
1
+
v
2
x
−
1
−
v
2
x
−
2
+
v
2
×
f
[
x
−
2
]
f
[
x
]
=
v
2
x
−
v
2
x
−
2
+
v
2
×
f
[
x
−
2
]
f[x] = v^{2x}-v^{2x-1} + v \times f[x-1] \\ \, \\ v \times f[x-1] =v \times (v^{2x-2}-v^{2x-3}+v \times f[x-2]) \\ \, \\ f[x] = v^{2x}-v^{2x-1}+ v^{2x-1} - v^{2x-2} + v^2 \times f[x-2] \\ \, \\ f[x] = v^{2x}-v^{2x-2} + v^2 \times f[x-2]
f[x]=v2x−v2x−1+v×f[x−1]v×f[x−1]=v×(v2x−2−v2x−3+v×f[x−2])f[x]=v2x−v2x−1+v2x−1−v2x−2+v2×f[x−2]f[x]=v2x−v2x−2+v2×f[x−2]
继续化简,得到:
f
[
x
]
=
v
2
x
−
v
2
x
−
3
+
v
3
×
f
[
x
−
3
]
…
f
[
x
]
=
v
2
x
−
v
2
x
−
(
x
−
1
)
+
v
x
−
1
×
f
[
x
−
(
x
−
1
)
]
f
[
x
]
=
v
2
x
−
v
x
+
1
+
v
x
−
1
×
f
[
1
]
f[x]=v^{2x}-v^{2x-3}+v^3 \times f[x-3] \\ \dots \\ f[x]=v^{2x}-v^{2x-(x-1)} + v^{x-1} \times f[x-(x-1)] \\ \, \\ f[x]=v^{2x}-v^{x+1} + v^{x-1} \times f[1]
f[x]=v2x−v2x−3+v3×f[x−3]…f[x]=v2x−v2x−(x−1)+vx−1×f[x−(x−1)]f[x]=v2x−vx+1+vx−1×f[1]
f [ 1 ] f[1] f[1] 是边界情况,即左右两侧被一元限制了, f [ 1 ] = 1 + ( v − 1 ) × v f[1]= 1 + (v-1) \times v f[1]=1+(v−1)×v。带进去得:
f [ x ] = v 2 x − v x + v x − 1 。 f[x]=v^{2x}-v^x+v^{x-1}。 f[x]=v2x−vx+vx−1。
可以用快速幂直接求解了。对于两头的情况:
- 左侧到第一个一元限制位置假设有 x x x 个二元限制,则答案明显为 v 2 x v^{2x} v2x。
- 最后一个一元限制位置到右侧,如果该一元限制的位置取值不和限制相同,为 ( v − 1 ) × v × v 2 x − 2 (v-1) \times v \times v^{2x-2} (v−1)×v×v2x−2,否则为 v × v 2 x − 2 v \times v^{2x-2} v×v2x−2,为 v 2 x v^{2x} v2x。
整体时间复杂度 O ( T m l o g n ) O(Tmlogn) O(Tmlogn)。
(2)以下是正难则反的思想,很有启发性,记录下来。对于以上说的连读的区间,如果从左侧的一元限制位置往右推,推到右侧的一元限制位置时,发生矛盾了,比如区间是 [ i , j ] [i,j] [i,j],最后 b j − 1 b_{j-1} bj−1 不等于 x j x_j xj,此时就发生了矛盾。总的方案是 v 2 ( j − i ) v^{2(j-i)} v2(j−i),不合法的方案是: a i a_i ai 一定等于 x i x_i xi, b i b_i bi 有 v v v 种取值, a i + 1 a_{i+1} ai+1 和 b i b_i bi 相等,有一种取值, b i + 1 b_{i+1} bi+1 有 v v v 种取值, … \dots …,最后的 b j − 1 b_{j-1} bj−1 有 v − 1 v-1 v−1 种取值,因为不能和 x j x_j xj 相等,需发生矛盾,不合法的方案数为 v j − i − 1 × ( v − 1 ) v^{j-i-1} \times (v-1) vj−i−1×(v−1),相减就是合法的方案: v 2 ( j − i ) − v j − i − 1 × ( v − 1 ) v^{2(j-i)}-v^{j-i-1} \times (v-1) v2(j−i)−vj−i−1×(v−1)。如果设 x x x 表示区间二元限制的数量,则 x = j − i x=j-i x=j−i,则方案为: v 2 x − v x + v x − 1 v^{2x}-v^x+v^{x-1} v2x−vx+vx−1。和上面一致。
3.树的遍历
题意:树上。两条边有公共结点,则这两条边相邻。定义一种类似 d f s dfs dfs 的遍历方式,定义一种新的结点:一条边 ( u , v ) (u,v) (u,v) 为一个新的结点。两条边相邻的新的结点可以访问。给定 k k k 条关键边,以任意一条关键边作为起始边遍历,遍历在新的结点间进行,即一条边遍历到另一条边。问能得到的新树的种类。取模。 n ≤ 1 0 5 , 1 ≤ k < n n \le 10^5, 1 \le k < n n≤105,1≤k<n。
分析:先从小数据
k
=
1
k=1
k=1 的情况思考,也就是只有一条起始边作为根。
边上的点称之为方点。假设 ( 1 , 2 ) (1,2) (1,2) 上的方点为关键边,蓝色边是其方点构树的一种。可以观察到性质:在原树中,同一层的边连起来是一条链,上层向他这一层连一条边,他这一层向下一层连一条边,具体连哪条边有多种选择,比如 2 2 2 号点下面的四个方点,其中一个连上一层的边,一个连下一层的边, 4 4 4 个方点的不同方案有 4 ! 4! 4! 种。设原树中每个点的度为 d i d_i di,则 k = 1 k=1 k=1 的时候答案为 ∏ i = 1 i = n ( ( d i − 1 ) ! ) \prod_{i=1}^{i=n} ((d_i-1)!) ∏i=1i=n((di−1)!)。
现在考虑
k
=
2
k=2
k=2 的情况。容易想到,如果有两条关键边,分别以每条关键边跑答案相加,结果会有重复的地方。比如
(
1
,
2
)
(1,2)
(1,2) 和
(
6
,
10
)
(6,10)
(6,10) 为关键边,上图的构树是同一种方案。现在考虑如何去掉重复的方案。观察发现,只要这两条关键边在新构树中属于一条链,分别以他们为关键边构成的树是相同的。这条链上的点的方案为
∏
i
∈
链
(
d
i
−
2
)
!
\prod_{i \in 链}{(d_i-2)!}
∏i∈链(di−2)!。因为链上的点的出点是固定的,所以链上每个点的贡献是
(
d
i
−
2
)
!
(d_i-2)!
(di−2)!,不含这条链的两端的点,两端的点的贡献依然是
(
d
i
−
1
)
!
(d_i-1)!
(di−1)!。
(
d
i
−
2
)
!
=
(
d
i
−
1
)
!
(
d
i
−
1
)
(d_i-2)!=\frac{(d_i-1)!}{(d_i-1)}
(di−2)!=(di−1)(di−1)!,所以总的答案为:
∏
i
=
1
i
=
n
(
d
i
−
1
)
!
×
∏
i
∈
链
(
d
i
−
1
)
−
1
\prod_{i=1}^{i=n} (d_i-1)! \times \prod_{i \in 链} (d_i-1)^{-1}
i=1∏i=n(di−1)!×i∈链∏(di−1)−1
对于 k > 2 k > 2 k>2 的情况,考虑容斥。设 g ( x ) g(x) g(x) 表示链上有 x x x 个关键边的树的方案,最后的总答案为 ∑ ( − 1 ) x + 1 g ( x ) \sum (-1)^{x+1} g(x) ∑(−1)x+1g(x)。 g ( 1 ) g(1) g(1) 和 g ( 2 ) g(2) g(2) 的值已经算出来了,现在考虑计算 g ( l ) , l ≥ 3 g(l), l \ge 3 g(l),l≥3。关键边能作为根的一定在一条链上,对于有 l l l 个关键边的链,取出 i i i 个关键边的贡献是 C l − 2 i − 2 g ( 2 ) C_{l-2}^{i-2} g(2) Cl−2i−2g(2), g ( 2 ) g(2) g(2) 指的是两头的关键边。将该贡献带入前面容斥的式子,有贡献 ( − 1 ) i + 1 C l − 2 i − 2 g ( 2 ) (-1)^{i+1}C_{l-2}^{i-2}g(2) (−1)i+1Cl−2i−2g(2),将这个组合式子展开发现,对于 l ≥ 3 l \ge 3 l≥3 的情况,贡献是 0 0 0(杨辉三角中每一行的值正负相隔,加起来和为 0 0 0)。因此,不用考虑关键边数量大于等于 3 3 3 的链。
只用考虑 l ≤ 2 l \le 2 l≤2 的链的情况。
(1)把关键边断开,变成一堆森林,然后对森林里的每一棵树,跑一个换根 DP,对每一个跟关键边相接的点统一计算它连的关键边和其它关键边之间的贡献。大致原理是先预先乘个
∏
(
d
i
−
1
)
!
\prod (d_i-1)!
∏(di−1)!,然后遇到一个点就乘上
(
d
i
−
1
)
−
1
(d_i-1)^{-1}
(di−1)−1。
(2)树形dp。单独求出每条关键边为根的答案之和,然和减去两条关键边同时能为根的方案。设
f
[
u
]
f[u]
f[u] 表示
u
u
u 子树内是否有关键边,如果有要依次乘上
(
d
i
−
1
)
−
1
(d_i-1)^{-1}
(di−1)−1,如果没有本身置为
−
1
-1
−1。对于
u
u
u 的儿子结点
v
v
v,如果
f
[
v
]
f[v]
f[v] 不为
−
1
-1
−1,说明
v
v
v 子树内有关键边,如果此时
u
u
u 为关键边的一个点,则统计答案。
线性时间复杂度。
特殊性质分: k = 1 k=1 k=1,链,菊花图。
4.树上查询
题意: n n n 个结点的树, 1 1 1 是根结点, 1 1 1 的深度为 1 1 1,其他结点的深度依次递增。定义 l c a ∗ ( l , r ) lca*(l,r) lca∗(l,r) 表示结点编号在 [ l , r ] [l,r] [l,r] 之间的所有的点的最近公共祖先。 q q q 个查询,每次给定 ( l , r , k ) (l,r,k) (l,r,k) ,问 [ l , r ] [l,r] [l,r] 中任意长度大于等于 k k k 的连续子区间的最近公共祖先深度的最大值。 1 ≤ n , q ≤ 5 × 1 0 5 1 \le n,q \le 5 \times 10^5 1≤n,q≤5×105。
分析:设 l c a ( u , v ) lca(u,v) lca(u,v) 表示 u , v u,v u,v 两个点的最近公共祖先, d e p u dep_u depu 表示 u u u 点的深度。观察(猜测)知道: l c a ∗ ( l , r ) = max { l c a ( i , i + 1 ) } , l ≤ i < r lca*(l,r)=\max\{lca(i,i+1)\}, l \le i \lt r lca∗(l,r)=max{lca(i,i+1)},l≤i<r。对每个 l c a ( i , i + 1 ) lca(i,i+1) lca(i,i+1) 的结点,求出以该结点为 l c a lca lca 的最大连续区间 [ x i , y i , v i ] [x_i,y_i,v_i] [xi,yi,vi], v i v_i vi 表示这个结点的深度。问题转化为:有 n − 1 n-1 n−1 个线段,每个线段带权值,每次询问给定一条线段,求该条线段和这 n − 1 n-1 n−1 条线段交集大于等于 k k k 的线段的最大权值。
设 a i a_i ai 为 l c a ( i , i + 1 ) lca(i,i+1) lca(i,i+1) 的结点深度,构建二元组 ( i , a i ) (i, a_i) (i,ai) 建立笛卡尔树,能求出结点 ( i , a i ) (i,a_i) (i,ai) 以 a i a_i ai 为最大值的结点区间 [ x i , y i ] [x_i,y_i] [xi,yi],实际代表的结点区间是 [ x i , y i + 1 , v i ] [x_i,y_i+1,v_i] [xi,yi+1,vi]。
对于询问 [ l , r ] [l,r] [l,r] 来说,考虑能对该询问产生贡献的线段 [ L , R ] [L,R] [L,R] 需满足:
l
≤
L
≤
r
≤
R
l \le L \le r \le R
l≤L≤r≤R
L
≤
l
≤
R
≤
r
L \le l \le R \le r
L≤l≤R≤r
L
≤
l
≤
r
≤
R
L \le l \le r \le R
L≤l≤r≤R
l
≤
L
≤
R
≤
r
l \le L \le R \le r
l≤L≤R≤r
前两种是相交,后两种是包含。对于第 3 3 3 种,询问线段完全被某条线段或者多条线段包含,由于 r − l + 1 ≥ k r-l+1 \ge k r−l+1≥k,不需要讨论 k k k 的大小,二维偏序解决,即查询满足 L ≤ l L \le l L≤l,且 R ≥ r R \ge r R≥r 的最大的权值,先对所有的 L L L 排序,然后树状数组维护 R R R 的位置,每个位置上填上权值。
对于第 1 1 1 种,不仅要考虑 L , R L,R L,R 和 l , r l,r l,r 的大小关系,还需要考虑 k k k 的问题,移向有 L ≤ r − k + 1 , R ≥ r L \le r -k +1,R \ge r L≤r−k+1,R≥r。二维偏序解决。第 2 2 2 种情况同理。
对于第 4 4 4 种情况,需要满足 R − L + 1 ≥ k R-L+1 \ge k R−L+1≥k,从大到小枚举 k k k,每次选择区间长度大于等于 k k k 的线段,将权值放在左端点 L L L 处,对于单次查询 [ l , r , k ] [l,r,k] [l,r,k],即是查询 [ l , r − k + 1 ] [l, r-k+1] [l,r−k+1] 的区间最大值。时间复杂度 O ( ( n + q ) l o g n ) O((n+q)logn) O((n+q)logn)。
也可参考如下: