题解:P16356 「Diligent-OI R3 D」神秘树
HoshinoIchika · · 题解
爆标爽。
考虑证明一个结论:对于任意正整数
证明是简单的:
- 若
y > x ,则x \bmod y = x \ge x \bmod z 。 - 若
\frac x2 < y \le x ,有x \bmod y = x - y 。而显然x \bmod z - y \bmod z \le x - y 。
那么对于一个结点序列
考虑链怎么做。维护一个类似单调队列的东西,每次:
- 暴力枚举队内的点向点
i 转移; - 把队头
a_j < 2a_i 的点j 弹出; - 把队尾距离不合法的点弹出;
- 然后将点
i 入队。
队列中相邻的两个点
::::info[参考实现]
void dp(int u, int fa, deque<int> q){
while (q.size() && de[q.front()] < de[u] - k) q.pop_front();
for (int x : q) tmax(f[u], f[x] + a[x] % a[u]);
while (q.size() && a[q.back()] < a[u] << 1) q.pop_back();
q.push_back(u), tmax(ans, f[u]);
for (int i = G.h(u);i != -1;i = G[i].nxt){
int v = G[i].v;if (v == fa) continue;
de[v] = de[u] + 1, dp(v, u, q);
}
}
::::