2023 杭电多校 Day1

1009

签到, 队友哥切的, 没看

1002

\(f(x, 0/1/2)\) 表示当前点没有覆盖/覆盖/放置观察点 子树内最小代价, 简单转移即可。

f[x][1] = 1e18;
f[x][2] = a[x]; f[x][0] = 0;
for (int y : e[x]) if (y != fx) {
	dfs(y, x);
	static i64 g[3];
	g[0] = g[1] = g[2] = 1e18;
	g[1] = f[x][0] + f[y][2];
	g[1] = std :: min( {g[1], f[x][1] + f[y][2], f[x][1] + f[y][1] } );
	g[2] = std :: min( {g[2], f[x][2] + f[y][0], f[x][2] + f[y][1], f[x][2] + f[y][2]} );
	g[0] = std :: min( {g[0], f[x][0] + f[y][1]} );
	g[1] = std :: min( {g[1], f[x][0] + f[y][2]} );
	f[x][0] = g[0];
	f[x][1] = g[1];
	f[x][2] = g[2];
}

1010

这个一看就是 \(x\) 递增条件比较关键, 可以观察到当 \(a_i\) 第一次比 \(x\) 小以后, 以后的操作都是取反然后加上 \(x\)

我的做法就是开一个线段树维护原来的序列, 开一个线段树维护另外一个序列, 每次发现区间有值会第一次比 \(x\) 小就暴力递归下去把这个值删掉, 然后加入另外一个线段树。这样的话每次在两棵线段树上面区间取反, 区间加法。在第一个线段树上发现有要删掉的点就暴力递归, 复杂度一个 \(\log\)

code

1005

最小表示法即可。

比赛的时候学长写了个倍长再哈希的做法, 还被卡常数了(

真正的战犯往往没有写这题的代码

1006

\(10\) 组询问一看就是用来暴力的。

一眼 DP, 设 \(f_x\) 表示跳到 \(x\) 的最小代价, 转移就是

\[f_x = \min_{y \in subtree(x)} \{f_y + (d_y - d_x - L) ^ 2\} \]

经典斜率优化形式, 但是显然我事不会去写启发式合并平衡树维护的凸包的, 也不想去写什么定期重构之类的鬼东西, 点分治斜率优化也行, 但是还是懒得写, 所以选择使用李超树维护。

李超树合并即可。

李超树合并和普通线段树合并基本一致, 只是当两边存在的时候多了一个插入直线的操作, 但是事实上加入操作以后仍然是单 \(\log\) 的。

复杂度不记得怎么证明了, 反正跑得快。

code

1012

\[SG(x) = \text{xor}_{fa_y =x} (SG(y) + 1) \]

换根维护一下即可。

结论来自于 POJ3710

1003

区间 dp, 赛时没时间写完了。其实是赛时马上就要结束了没注意到等级会小于等于7懒得写了

注意到这个以后直接 \(dp(l, r, x, k)\) 表示 \((l, r)\) 区间,留下 \(x\) 等级 \(k\) 号卡片, 简单转移一下就做完了。

code

1001

队友哥写的, 可惜 G 了。

暴力枚举相交路径上每一个点计算相遇最短时间, 直接 exgcd 算最小解即可, 代码还没写, 睡觉觉捏

posted @ 2023-07-18 23:01  HN-wrp  阅读(78)  评论(0编辑  收藏  举报