题意
ETT 的一种解释:对大小为 n n n 的树进行 dfs,记录每一步到达的点,生成长为 2 n − 1 2n-1 2n−1 的序列,称为该树的 ETT.
例如, n = 7 n=7 n=7 的满二叉树的一个 ETT 为 1 , 2 , 4 , 2 , 5 , 2 , 1 , 3 , 6 , 3 , 7 , 3 , 1 1,2,4,2,5,2,1,3,6,3,7,3,1 1,2,4,2,5,2,1,3,6,3,7,3,1.
设有大小为 n n n、以 1 1 1 为根 的树,现给出其 ETT 的一部分,请还原原 ETT。
#1(20pts): T = 10 , n ≤ 5 T=10,n\le 5 T=10,n≤5.
#2(30pts): T = 10 , n ≤ 1 0 3 T=10,n\le 10^3 T=10,n≤103.
#3(50pts): ∑ n ≤ 5 × 1 0 5 \sum{n}\le 5\times 10^5 ∑n≤5×105.
保证有解。
题解
发现两个给定的相同的数
x
x
x之间的数一定是
x
x
x的一个子树的欧拉序,考虑把每两个相同的数之间的欧拉序先确定,注意到这中间不会有给定的相同的数(如果有就会先处理掉),做完后把这个区间缩成
x
x
x,最后就变成一个没有给定重复的数的序列,和刚才的问题是一样的。
考虑如何把一个头尾确定,中间给定的数没有重复的数的?
确定。因为是欧拉序,考虑从前往后扫,维护一个栈代表从根到当前节点的路径,遇到一个给定的数,直接模拟;遇到?
,有三种选择:填一个和栈的倒数第二个相同的数,填一个新的数,或填一个与后面某个数相同的数。我们的原则应是尽量不新增数,且保证尽量多位置合法(其实两者是共通的)。设后面一个给定数的位置为
j
j
j,当
(
s
j
−
s
i
−
1
)
∗
2
=
j
−
i
(s_j-s_i-1)*2=j-i
(sj−si−1)∗2=j−i(
s
s
s为给定数的个数的前缀和)时,如果
i
i
i填了
a
j
a_j
aj,那么中间的?
填恰好可以用中间的数填完。这样做可以保证后面一段是合法的,同时不会影响到前面,所以应先考虑这种做法(如果先考虑前面,就可能使后面不合法)。如果不是这样的
j
j
j,或者会新增数或者不能填,都无需考虑。用
v
e
c
t
o
r
vector
vector维护一下
s
i
−
i
s_i-i
si−i相同的下标(不要用stack,会MLE),如果有的话取最小的,否则考虑弹栈,再不行就新增一个数。