集训日志
好的,新开了个博客,记题解的。
10.1
靠,懒不了了,口述题面吧。
T1
给一个 01 序列,每次交换两个位置的代价是 \(|i-j|^k\),\(k\) 已经给定,求使得序列变成 01 交替的最小代价。
注意到 \(k \leq 1\) 时才是有效的,更大的就可以拆成小的交换,然后就做完了。
T2
给 \(m\) 个区间,每个区间有代价 \(c_i\),每个点有最大覆盖次数 \(p_i\),求至少覆盖 \(k\) 个点的最小代价。
对于 \(p_i = 1\) 也就是每个区间无交集,设计 \(f_{i,j}\) 表示前 \(i\) 个点选了 \(j\) 个的最小代价,然后 \(O(n)\) 转移,复杂度 \(O(n^2)\),转移是 \(f(i,j) = \min \left \{ f(l-1,j-len)+w(l,j)\right \}\)
考虑拓展一般情况,我好像已经想到了,然后莫名其妙 hack 了自己,发现当 \(p_i\) 无取值要求时,一个点最多只会被俩区间覆盖,然后 \(p_i\) 就只有为 \(1\) 和不为 \(1\) 两种取值,对于为 \(1\),就和 Sub 1 相同,不为 1 时,他还能再被覆盖一次,假设后面我们枚举了一个 \(k\),那么 \([k,j]\) 仍然是有贡献的,所以就再前面 \(p_i\) 等于 \(1\) 的时候多进行一步转移就好了,复杂度 \(O(n^3)\)。
还是讲一下具体实现过程,我们称一段 \(>1\) 连续的 \(p\) 序列为“可拓展的”,我们先枚举右端点再枚举左端点,此时考虑枚举左端点的过程中,我们总是想要一段“可拓展的”块,也就是大概 11111222222222 i
,\(i\) 前面的 \(2\) 都是可覆盖的,那么我们就是找这样的块,然后取这样的块内最小值转移就好了,就是这样:
fo(1,i,n){
fo(1,j,i) f[i][j]=f[i-1][j];
ll minx=INF;
fo(1,l,i){
if(a[l][i]<minx||p[l-1]!=1){
minx=min(minx,a[l][i]);
fo(1,j,i) if(j-i+l-1>=0&&j-i+l-1<=l-1) f[i][j]=min(f[i][j],f[l-1][j-i+l-1]+minx);
}
else if(p[l-1]==1) minx=INF;
}
}
T3
一棵树,两个操作,将 \(u\) 到 \(v\) 都连在一起,求 \(u\) 到 \(v\) 路径上有多少连通块。
树剖板子,但是 \(O(n\log^2 n)\) 被卡了,这就是大常熟树剖的优势。
发现边转点之后,给每个点一个颜色,表示自己跟父亲有没有边相连,没有为白色,那么答案就是链上的白点数量,然后就是树剖板子,这样是 \(O(n\log^2 n)\) 的,期望 60~100,大常熟的奇妙之处。
发现既然是记录白点数量,树状数组就能干了,记录和再容斥掉 lca 的答案,点修单改都是 \(O(\log)\) 的,所以期望 100。
T4
\(N\) 皇后,有不能放的位置,求方案数。
不会容斥,不会容斥,不会容斥。
一步一步来,考虑如何判断每个对角线都有一个车,就是总方案数 \(n!\) 容斥掉没有车在对角线上的情况,然后处理不让放的点,发现 \(m\leq 10\),所以直接枚举不让放的点,子集枚举,然后再容斥掉这个时候所有的方案数,最后还要再容斥掉同时满足上面三个条件的情况,所以复杂度 \(O(2^mn^2)\)。
10.2
最丑陋的一场。
T1
给一个序列求在模 \(m\) 的情况下最大的子序列和,\(n\leq 35 ~ a_i \leq 10^9 ~ m \leq 10^9\)。
看到 \(n\leq 35\) 就往折半搜索想了,直接折半搜索,然后合并两堆数字,数字合并过程排序后贪心二分即可。
T2
给一个小写字符串,求不同子序列个数。
发现都是小写字母,直接枚举子序列可能是什么,然后扔进去匹配,记录 \(pre_{i,j}\) 表示第 \(i\) 个位置前面第一个 \(j\) 字母在哪里,直接硬匹配就好了,复杂度 \(O(26^4)\)。
T3
两个人在 \(n\times n\) 方格上走,每次向下或向右,小 W 可以选择不超过三个数,选择之后小 B 走,小 B 选择的数的最大值不能达到小 W 数的最小值,个数不能超过小 W 选的数字个数,记他们两个拿的数字之和为价值,求价值最大值。\(n\leq 15\)
考虑暴力枚举小 W 选的点,然后 \(O(n^2)\) dp 小 B 检查,这样做是 \(O(n^8)\) 的,无法通过。
发现每次只能向下或向右,那么确定一个点之后下一个点只会在他的右下角,而且每个点只会对后面的点有影响,我们只需要枚举小 W 的前两个点,然后找第二个点右下角的最大值就好了,因为显然取更小值更劣,所以复杂度 \(O(n^6)\) 可以通过。
T4
一堆区间,一堆询问,每次询问求至少多少区间能覆盖这个询问区间。
先只考虑一个点时怎么做,显然我们当前的最优结果就是向右走的最远,也就是对区间排序后的前缀最大右端点,记前缀最大右端点为 \(pre_i\),那么我们下一个选择的点就是 \(pre_{pre_i}\),依次叠加,但是可能被单调递增序列卡掉,复杂度退化为 \(O(n^2)\),有 30 分。
考虑优化,发现每一个跳到下一个决策位置的过程很类似树上求 LCA,直接倍增优化此过程,复杂度 \(O(n\log n)\),可以通过。