今天去讲课,讲着讲着发现自己忘怎么做了,脸丢尽了,呜呜呜
铺设道路
考场上直接上的线段树 ,就是找到最小的,然后递归求解
货币系统
将货币排序,如果当前不能被表示,就把它加上,并且把背包的当前值域用它更新到下一个,这样下一个的时候就知道能不能被表示了,复杂度
O
(
T
n
a
i
)
O(Tna_i)
O(Tnai)
赛道修建
考虑二分答案,难就难在检验
有一种贪心就是在一棵子树中,尽量多凑成一整条道路,然后保留一条最长的与上面的合并,不妨用
f
i
f_i
fi表示最长的长度
每次合并子树中的
f
i
f_i
fi,就是将它们插入
s
e
t
set
set, 然后从第一个开始枚举,然后查
l
o
w
e
r
b
o
u
n
d
(
m
i
d
−
f
i
)
lowerbound(mid-f_i)
lowerbound(mid−fi),然后将它们删除
最后在
s
e
t
set
set 里面取一个最大的作为现在的
f
u
f_u
fu
旅行
暴力枚举断边,然后
d
f
s
dfs
dfs 一遍看是不是一棵树,如果是就跟答案比一下
边先按儿子编号排好序,复杂度
O
(
n
2
)
O(n^2)
O(n2)
填数游戏
咕咕咕
50
p
t
s
50pts
50pts也是可观的分数,但是打表的思想还是要有
保卫王国
动态DP,考虑用树剖来维护
首先有
f
u
,
0
=
∑
f
t
,
1
f_{u,0} = \sum f_{t,1}
fu,0=∑ft,1,
f
u
,
1
=
∑
m
i
n
(
f
t
,
0
,
f
t
,
1
)
f_{u,1} =\sum min(f_{t,0}, f_{t,1})
fu,1=∑min(ft,0,ft,1)
先不考虑重儿子的转移,令不考虑的为
f
u
,
0
/
1
′
f'_{u,0/1}
fu,0/1′
f
u
,
0
=
f
u
,
0
′
+
f
s
o
n
,
1
f_{u,0} = f'_{u,0}+f_{son,1}
fu,0=fu,0′+fson,1,
f
u
,
1
=
f
u
,
1
′
+
m
i
n
(
f
s
o
n
,
0
,
f
s
o
n
,
1
)
f_{u,1} =f'_{u,1}+min(f_{son,0}, f_{son,1})
fu,1=fu,1′+min(fson,0,fson,1)
用一个经典的满足结合律的矩阵乘法来转移(加变max,乘变加)
(
f
u
,
0
f
u
,
1
)
=
(
f
s
o
n
,
0
f
s
o
n
,
1
)
∗
(
∞
,
f
u
,
0
′
f
u
,
1
′
,
f
u
,
1
′
)
\binom{f_{u,0}}{f_{u,1}}=\binom{f_{son,0}}{f_{son,1}}*\binom{∞,f'_{u,0}}{f'_{u,1}, f'_{u,1}}
(fu,1fu,0)=(fson,1fson,0)∗(fu,1′,fu,1′∞,fu,0′)
=
(
f
s
s
o
n
,
0
f
s
s
o
n
,
1
)
∗
(
∞
,
f
u
,
0
′
′
f
u
,
1
′
′
,
f
u
,
1
′
′
)
(
∞
,
f
u
,
0
′
f
u
,
1
′
,
f
u
,
1
′
)
=\binom{f_{sson,0}}{f_{sson,1}}*\binom{∞,f''_{u,0}}{f''_{u,1}, f''_{u,1}}\binom{∞,f'_{u,0}}{f'_{u,1}, f'_{u,1}}
=(fsson,1fsson,0)∗(fu,1′′,fu,1′′∞,fu,0′′)(fu,1′,fu,1′∞,fu,0′)
既然满足结合律就可以用线段树维护了
每次修改,先修改本身,再修改链顶,然后由链顶修改它
f
a
fa
fa的
f
f
a
,
0
/
1
′
f'_{fa,0/1}
ffa,0/1′
然后继续这样做直到跳到根,复杂度
O
(
n
l
o
g
2
n
)
O(nlog^2n)
O(nlog2n)
NOIP 2018 题解
最新推荐文章于 2022-05-20 09:11:28 发布