16
https://codeforces.com/contest/2178/problem/G
好难啊。
包含一条 chord 的 chain 数量为偶数,当且仅当以它结尾的 chain 数量为偶数,或者以它为开头的 chain 数量为偶数。
以它结尾的 chain 数量是好算的,用一个 BIT 维护异或就可以了。如果是偶数,那就不用管了。否则就给它赋个随机权值,然后异或哈希,用另一个 BIT 维护这个过程,就做完了。
https://www.luogu.com.cn/problem/P11824
枚举最大值,动态删点,然后相当于对于每个 \(x\),设此时包含 \(x\) 的独立集数量为 \(res_x\),就要令 \(ans_x\) 加上 \(res_x\times v\)。
top tree 维护动态 DP,然后 \(res_x\) 可以看作是从 \(id_x\) 到根的转移系数。考虑从上到下 pushdown 地递推转移系数,上面那个操作就是直接在根节点上打个 \(v\) 的 tag。
好像还能从转置的角度去理解这个东西,但是我不会啊!
http://xsy.gdgzez.com.cn/JudgeOnline/problem.php?cid=2368&pid=1
考虑选取 \((1,a_1)\) 作为树根之后,一棵子树应该长什么样子。只有以下三种情况:
- 第 \([l,r]\) 行;
- 第 \([l,r]\) 行,但不包含区间内的第 \(x\) 行的一个后缀;
- 第 \([l,r]\) 行,但还包含区间外的第 \(x\) 行的一个后缀。
然后用三个状态 \(f,g,h\) 记录这三种情况,讨论一下转移。
看起来不是很复杂,但是感觉完全不是我能在 5h 内做出来的东西。
http://xsy.gdgzez.com.cn/JudgeOnline/problem.php?cid=2369&pid=1
大概是要把这么个过程变成线性:
for (int i = 1; i <= n; i++) {
node tmp = T.query(); tmp.mx++;
T.clear(1, 1, cc, 1, l[i] - 1); T.clear(1, 1, cc, r[i] + 1, cc);
T.chkmin(1, 1, cc, l[i], r[i], tmp);
sum += a[i];
}
注意到所有 node 的第一维至多只有两种取值,且只相差 \(1\),chkmin 操作并不会更改 node 的第一维。直接 deque 维护连续段。
https://www.luogu.com.cn/problem/P10656
注意到有两组平凡的解,分别是 \(\sum x\) 和 \(\sum y\)。这说明在最优方案里,要么选出的 \(x\) 之和大于所有 \(x\) 总和的一半,要么选出的 \(y\) 之和大于所有 \(y\) 总和的一半。不妨设是 \(x\) 的和大于一半,那么第一个使得前缀和大于一半的位置就是必选的。然后对 \(y\) 的右端点扫描线,维护每个左端点的答案,复杂度 \(O(n\log n)\)。
http://xsy.gdgzez.com.cn/JudgeOnline/problem.php?cid=2371&pid=1
有一个 \(O(n^3)\) 的暴力叫做,每次暴力找出所有割边然后删掉。用 bitset 优化找割边的过程:找出一棵 dfs 树,维护子树内的邻域并集,复杂度就变成了 \(O(\frac{n^3}{w})\)。

浙公网安备 33010602011771号