content
A. Average Height
点点点
B. TMT Document
点点点
C. The Sports Festival
题意:
给定
n
(
1
⩽
n
⩽
2
⋅
1
0
3
)
n\left(1\leqslant n\leqslant 2\cdot 10^3\right)
n(1⩽n⩽2⋅103)个数,对其重排列。定义
d
i
=
m
a
x
(
a
1
,
a
2
,
.
.
.
,
a
i
)
−
m
i
n
(
a
1
,
a
2
,
.
.
.
,
a
i
)
d_i = max(a_1, a_2, ..., a_i) - min(a_1, a_2, ..., a_i)
di=max(a1,a2,...,ai)−min(a1,a2,...,ai),求最小的
∑
i
=
1
n
d
i
\sum_{i=1}^{n} d_i
∑i=1ndi。
题解:
在排列
a
1
,
a
2
,
.
.
.
,
a
i
a_1, a_2, ..., a_i
a1,a2,...,ai中,记最大值为
a
k
a_k
ak,如果
k
≠
i
k \neq i
k=i,那么
d
j
=
m
a
x
(
a
1
,
a
2
,
.
.
.
,
a
j
)
−
m
i
n
(
a
1
,
a
2
,
.
.
.
,
a
j
)
=
a
k
−
m
i
n
(
a
1
,
a
2
,
.
.
.
,
a
j
)
d_j = max(a_1, a_2, ..., a_j) - min(a_1, a_2, ..., a_j) = a_k - min(a_1, a_2, ..., a_j)
dj=max(a1,a2,...,aj)−min(a1,a2,...,aj)=ak−min(a1,a2,...,aj),其中
k
⩽
j
⩽
i
k \leqslant j \leqslant i
k⩽j⩽i,那么我们对
a
k
,
a
k
+
1
,
.
.
.
,
a
i
a_k, a_{k + 1}, ..., a_i
ak,ak+1,...,ai按从小到大排序,一定能获得
d
j
d_j
dj的更优解。最小值也是同样的情况,那么我们可以知道在已有排序
a
l
,
a
l
+
1
,
.
.
.
,
a
r
a_l, a_{l + 1}, ..., a_r
al,al+1,...,ar的情况下,两侧新加的值要么是未出现的最小最大值,要么是未出现的最大最小值,进一步的,
a
l
,
a
l
+
1
,
.
.
.
,
a
r
a_l, a_{l + 1}, ..., a_r
al,al+1,...,ar在大小上应该覆盖了一个连续区间。这时候我们先考虑对
a
i
a_i
ai快排,使得有序。然后这就变成了一个经典的dp问题,
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示
[
i
,
i
+
j
−
1
]
[i, i + j - 1]
[i,i+j−1]的最小
∑
k
=
i
i
+
j
−
1
d
k
\sum_{k=i}^{i + j - 1} d_k
∑k=ii+j−1dk,由
d
p
[
i
]
[
j
−
1
]
,
d
p
[
i
+
1
]
[
j
−
1
]
dp[i][j - 1], dp[i + 1][j - 1]
dp[i][j−1],dp[i+1][j−1]转移得到。时间复杂度为
O
(
n
2
)
O(n^2)
O(n2)。
D. Binary Literature
题意:
T
(
1
⩽
T
⩽
1
0
4
)
T\left(1\leqslant T\leqslant 10^4\right)
T(1⩽T⩽104)组数据。
每组数据给定
n
(
1
⩽
n
⩽
1
0
5
)
n\left(1\leqslant n\leqslant 10^5\right)
n(1⩽n⩽105)和三个长度为
2
n
2n
2n的字符串
s
1
,
s
2
,
s
3
s_1, s_2, s_3
s1,s2,s3。字符串由
0
,
1
0, 1
0,1构成。求一个长度为
3
n
3n
3n的字符串
S
S
S使得,S中存在和
s
1
,
s
2
,
s
3
s_1, s_2, s_3
s1,s2,s3中至少两个字符串相同的两个子序列。
∑
n
⩽
1
0
5
\sum{n} \leqslant 10^5
∑n⩽105
题解:
构造法。
法一:对字符串
s
i
s_i
si,因为仅有
0
,
1
0,1
0,1,那么存在一个出现次数
⩾
n
\geqslant n
⩾n的字符,而有三个字符串,则必然有一个字符在两个字符串中出现次数
⩾
n
\geqslant n
⩾n,记字符为
c
h
ch
ch,字符串为
s
0
,
s
1
s_0, s_1
s0,s1。那么以
c
h
ch
ch为公共字符,增加另一个字符。总的长度必然
⩽
3
n
\leqslant 3n
⩽3n,这是显然的。
法二:记字符串 s i s_i si的下标为 l i l_i li,那么 s i [ l i ] s_i[l_i] si[li]中必然有两个相同的字符,输出并且对应的 l i + 1 l_i+1 li+1。直到有一个字符串已被遍历完,记此时输出了 k k k个字符,那么总共有 2 k 2k 2k个 + 1 +1 +1,并且有一个 l i = 2 n l_i = 2n li=2n,那么,其他两个 l i l_i li相加为 2 k − 2 n 2k - 2n 2k−2n,则必有一个 l i ⩾ k − n l_i \geqslant k - n li⩾k−n,输出该 s i s_i si的剩余字符,有 2 n − ( k − n ) = 3 n − k 2n - (k - n) = 3n - k 2n−(k−n)=3n−k个,构造完成。
E. Almost Sorted
题意:
T
(
1
⩽
T
⩽
1
0
3
)
T\left(1\leqslant T\leqslant 10^3\right)
T(1⩽T⩽103)组数据。
每组数据给定
n
,
k
(
1
⩽
n
⩽
1
0
5
,
1
⩽
k
⩽
1
0
18
)
n, k\left(1\leqslant n\leqslant 10^5, 1\leqslant k\leqslant 10^{18}\right)
n,k(1⩽n⩽105,1⩽k⩽1018),n表示
[
1
,
n
]
[1,n]
[1,n]的数组。对其排列,需要满足
a
i
+
1
⩾
a
i
−
1
a_{i + 1} \geqslant a_i - 1
ai+1⩾ai−1,输出第
k
k
k个这样的排列。排列之间的比较是字典序。
题解:
对一个特定满足条件的排列,可以分成多个依次单调减一的区间
[
l
k
,
r
k
]
[l_k, r_k]
[lk,rk]。又因为
l
k
+
1
⩾
r
k
−
1
l_{k + 1} \geqslant r_k - 1
lk+1⩾rk−1,如果等号成立,则两区间合并,否则考虑到不重复性,有
l
k
+
1
>
l
k
l_{k + 1} > l_k
lk+1>lk。进一步可以推导出
l
k
l_k
lk是单调递增的,并且
l
k
l_k
lk的排列和整个排列是一一对应的关系。
记T(n)表示长度为
n
n
n的所有排列数,那么
T
(
n
)
=
∑
i
=
1
n
T
(
n
−
i
)
T(n) = \sum_{i = 1}^{n} T(n - i)
T(n)=∑i=1nT(n−i),表示剩下长度分别为
n
−
i
n - i
n−i的情况,特别的,
T
(
0
)
=
1
T(0) = 1
T(0)=1。
记
S
(
n
)
=
∑
i
=
0
n
T
(
i
)
S(n) = \sum_{i = 0}^{n}T(i)
S(n)=∑i=0nT(i),则
S
(
n
)
=
∑
i
=
0
n
−
1
T
(
i
)
+
T
(
n
)
=
2
∑
i
=
0
n
−
1
T
(
i
)
=
2
S
(
n
−
1
)
=
2
n
S(n) = \sum_{i = 0}^{n - 1} T(i) + T(n) = 2 \sum_{i = 0}^{n - 1} T(i) = 2S(n - 1) = 2^n
S(n)=∑i=0n−1T(i)+T(n)=2∑i=0n−1T(i)=2S(n−1)=2n,则
T
(
n
)
=
S
(
n
)
−
S
(
n
−
1
)
=
2
n
−
1
T(n) = S(n) - S(n - 1) = 2^{n - 1}
T(n)=S(n)−S(n−1)=2n−1。找到这个规律后,我们就可以用二分快速找到需要的数。对于当前状况
(
n
,
k
)
(n, k)
(n,k),表示有
n
n
n个数需要排列,找到第
k
k
k个排列,只需要找到最大的
K
K
K,使得
∑
i
=
1
K
−
1
T
(
n
−
i
)
<
k
\sum_{i = 1}^{K - 1} T(n - i) < k
∑i=1K−1T(n−i)<k成立,并更新
(
n
,
k
)
(n, k)
(n,k)。那么时间复杂度为
O
(
n
l
o
g
k
)
O(nlogk)
O(nlogk)。
注意到
∑
i
=
1
K
−
1
T
(
n
−
i
)
=
2
n
−
1
−
2
n
−
K
\sum_{i = 1}^{K - 1} T(n - i) = 2^{n - 1} - 2^{n - K}
∑i=1K−1T(n−i)=2n−1−2n−K。进一步优化的方法是将
k
k
k转化为二进制,为1表示
a
i
+
1
=
a
i
−
1
a_{i + 1} = a_i - 1
ai+1=ai−1。需要注意的是,在这种情况下,需要将
k
−
1
k - 1
k−1,这是因为映射关系。另一点是转化后二进制对应的坐标是
[
0
,
n
−
2
]
[0, n - 2]
[0,n−2],而不是
[
1
,
n
−
1
]
[1, n - 1]
[1,n−1]。时间复杂度为
O
(
l
o
g
k
)
O(logk)
O(logk)。
这个转化的思路可以从两个角度得到。
- 直接考虑 2 n − 1 − 2 n − K 2^{n - 1} - 2^{n - K} 2n−1−2n−K,每次找到的 K K K对应了转化成二进制后的第一个1。
- 从之前的映射关系入手,即每个 l k l_k lk排列和整体排列的一一对应关系,那么对 a i + 1 = a i − 1 a_{i + 1} = a_i - 1 ai+1=ai−1赋1,其他赋0。并且这个二进制对应的排列是符合字典序的。