2024.8.13 test
A
\(n\) 个人之间有若干认识关系,你要把这些人划分为两个集合,使得集合里的每个人都认识偶数个人。
求方案数,\(n\le 1000\)。
设每个人的状态为 \(0/1\) 表示两个集合,那么第 \(i\) 个人在其集合里认识的人个数是 \(\sum_{j}(x_i\otimes x_j\otimes 1)\)。
解这个方程,高斯消元,若自由元的个数是 \(x\),那么答案是 \(2^x\)。
B
有 \(n\) 个字符串,长度为 \(m\),你要计算有哪些字符串 \(i\),使得其他的所有字符串和恰好有 \(k\) 位不同。
\(n,m\le 2e5,nm\le 2e7\)。字符集由 ATCG 组成。
枚举第 \(i\) 个字符串,设 \(S_j\) 表示第 \(j\) 位与 \(i\) 不同的集合,那么 \(\cup S_j=k(\{1,2,3,4\}-i)\)。
判断集合相同,考虑和哈希,支持减去 \(i\) 即可。考虑随机给每个 \(i\) 赋一个权值即可。
C
有 \(n\) 座灯塔,高度为 \(h_i\),你可以使得某个 \(h\) 增加 \(1\),要使得每座灯塔都可以被另一座照明。
照明的条件是高度相同且中间没有更高的。问最小操作次数。\(n\le 1e5,h\le 1e9\)。
正解的话,我们首先建出大根的笛卡尔树。
考虑为了合法,对于 \(x\) 及其子树,我们必须要从 \(x\) 的左右子树里“拔高”至少一个点使其达到 \(h_x\)。
一个想法是拔高 \(3\) 个肯定不如拔高 \(2\) 个。设 \(dp_{x,c}\) 表示 \(x\) 子树钦定 \(c\) 个点拔高的最小代价。转移 \(O(1)\)。
复杂度线性。
D
一棵树上,你需要确定两个点 \(u,v\),最小化 \(\sum\min(dis_{i,u},dis_{i,v})\times a_i\)。
\(n\le 1e5\)。
枚举两个关键点势力范围的断边 \((u,fa)\),那么两个关键点一定设在 \(u\) 子树内重心和子树外重心上
转化求子树内外带权重心。
考虑一个经典结论:dfn 序中位数一定在重心的子树内。
而对于点带权,把中位数换成带权中位数还可以处理,求出中位数后树上倍增一下就能求出重心。
然后我们只要统计子树内或子树外内的点到重心的距离,考虑换根 dp,过程中用线段树维护每个点到当前节点的距离,区间距离乘权值之和也是很好线段树维护的。