时间安排
7:30–7:50 读题,T1是个 dp 或者数据结构维护贪心,T2数据结构,T3 可能是个邪门的 dp 。
7:50–8:30 T1, n ^ 2 的 dp 是显然的,但是这个 dp 貌似没有很好的优化空间。考虑有没有什么贪心之类的思路,手敲了一下拍不上。
8:30–9:30 T2,写完暴力。考虑 r=2 的特殊点,分讨一下发现情况比较复杂,直接做不太行。改变边权貌似可以看做加边删边,那么可以离线线段树分治,那么问题就是要实现动态的最小生成树,这个用重工业应该可做,不过比较麻烦难写而且常数是爆炸的,先跳过。
9:30–10:20 回过头看T1,这个 m 的限制目测有某种神秘的凸性,于是上 wqs二分,调参后拍上了。
10:20–11:00 T3,题目实际上要求一个生成树森林的权值,有暴力,可以用并查集维护。 n 很特殊,是 2 的幂,与之相关的要么是二进制之类的 dp ,要么就是多项式,想了一下这个 dp 应该做不了,于是就是多项式了,不过暂时想不到怎么和多项式扯上关系。
11:00–12:00 T2,对于动态最小生成树 lct 是可做的,于是要线段树分治套lct,还要实现撤销,麻烦点在于编号的定义,没有调出来。
回顾反思
T1:
发现答案关于操作次数不增,且每次能够多减少的次数递减,于是可以 wqs 二分。
在这道题花的时间有点多了,对相关性质的猜想分析可以更大胆一些。
T2:
对于离线部分分,有两种做法:
一是 lct+线段树分治;二是 cdq [HNOI2010]城市建设
对于正解的在线做法:
考虑对于网格图上各点的最小生成树,剩下的边构成其对偶图的最大生成树,于是两者互为补充,用lct分别维护两个树,当边权有变化是考虑两棵树之间边的交换即可。
要再熟悉熟悉 lct 。
wxq什么都做过tql tql orz orz
T3:
部分分:
首先可惜的一点是没有拿到矩阵树定理的 20 分,对于求解生成树森林的边权乘积和,建立一个虚点,相当于所有的树根连向虚点构成一个大树,然后钦定虚点为有根树的根即可。
正解:
将矩阵树定理的矩阵列出来:
[
S
+
1
−
w
1
−
w
2
⋯
−
w
n
−
1
−
w
n
−
1
S
+
1
−
w
1
⋯
−
w
n
−
2
⋮
⋮
⋱
⋮
−
w
1
−
w
2
−
w
3
⋯
S
+
1
]
\begin{bmatrix} {S+1}&{-w_1}&{-w_2}&{\cdots}&{-w_{n-1}}\\ {-w_{n-1}}&{S+1}&{-w_1}&{\cdots}&{-w_{n-2}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {-w_1}&{-w_2}&{-w_3}&{\cdots}&{S+1}\\ \end{bmatrix}
S+1−wn−1⋮−w1−w1S+1⋮−w2−w2−w1⋱−w3⋯⋯⋮⋯−wn−1−wn−2S+1
如上,发现其为一个循环矩阵,设为
A
A
A 。其中
S
+
1
S+1
S+1 在本题中可视为常数。
构造范德蒙德矩阵
B
B
B :
[
1
1
1
⋯
1
ω
n
0
ω
n
1
ω
n
2
⋯
ω
n
n
−
1
⋮
⋮
⋮
⋱
⋮
w
n
0
w
n
n
−
1
w
n
2
(
n
−
1
)
⋯
w
n
(
n
−
1
)
(
n
−
1
)
]
\begin{bmatrix} {1}&{1}&{1}&{\cdots}&{1}\\ {\omega_n^0}&{\omega_n^1}&{\omega_n^2}&{\cdots}&{\omega_n^{n-1}}\\ {\vdots}&{\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {w_n^0}&{w_n^{n-1}}&{w_n^{2(n-1)}}&{\cdots}&{w_n^{(n-1)(n-1)}}\\ \end{bmatrix}
1ωn0⋮wn01ωn1⋮wnn−11ωn2⋮wn2(n−1)⋯⋯⋱⋯1ωnn−1⋮wn(n−1)(n−1)
构造多项式函数
f
(
x
)
=
S
+
1
+
∑
k
=
1
n
−
1
−
w
k
x
k
f(x)=S+1+\sum_{k=1}^{n-1}{-w_k}x^k
f(x)=S+1+∑k=1n−1−wkxk
利用
w
n
k
=
w
n
k
m
o
d
n
w_n^k=w_n^{k\mod n}
wnk=wnkmodn 可得到
A
B
AB
AB 为:
考虑到
∣
A
B
∣
=
∣
A
∣
∣
B
∣
|AB|=|A||B|
∣AB∣=∣A∣∣B∣
又观察到
∣
A
B
∣
=
∣
B
∣
∏
t
=
0
n
−
1
f
(
ω
n
t
)
|AB|=|B|\prod_{t=0}^{n-1}f(\omega_n^t)
∣AB∣=∣B∣∏t=0n−1f(ωnt)
得到
∣
A
∣
=
∏
t
=
0
n
−
1
f
(
ω
n
t
)
|A|=\prod_{t=0}^{n-1}f(\omega_n^t)
∣A∣=∏t=0n−1f(ωnt)
那么利用 DFT 算出相应
f
(
ω
n
t
)
f(\omega_n^t)
f(ωnt) 的点值乘起来即可。
这个矩阵的推导构造比较人类智慧,不过这个循环矩阵的结论是一般的,比较有可拓展性。