P5385 [Cnoi2019]须臾幻境
题目链接
题解
调了一个下午+一个晚上。我觉得可以进“消耗战合集”了。
再一次感受到调题调到崩溃的滋味 这点压力都承受不了,还怎么学OI?!
还是尽早进入正题为好。
首先一步转化,“连通块个数”转化为求连通块边数。如果连通块边数可以像gcd一样能用线段树维护就好了。可惜它不好合并。强制在线也限制了莫队(莫队似乎也做不了).差分啥的更别想了。
我们似乎走到了尽头?不过之前的一道旧试题提醒我们,这时贪心很可能是我们的救星。
与旧试题一样,加入一条边后,如果我们想要维护连通块的最简状态:树,那么我们需要断掉一条边。然而这条边是有选择的余地的,如果我们维护最靠后出现的边组成的森林,那么在目前右端点为 \(R\) 时,对于所有的 \(L\),选这个森林上的边都一定是最优的
然后方法就多了。我们可以维护每个时候的边的状态,用主席树来维护,查询的时候直接去 \(R\) 的主席树上区间查询;自然我们也可以维护每个点被“顶掉”的时间 \(t_i\),查询就直接在 \(L\) 到 \(R\) 的区间里面查 \(t_i > R\) 的个数,这实质是二维数点问题,我们可以用主席树随便维护一下。
不卡时间,不卡空间,考验码力。(然而最后错的还是些低级错误)
出错点
-
pushup
中只对“边”点进行了初始化,并没有给“点”点初始化为 \(\infty\)。 -
fa[son[cur][flag ^ 1]] = faa;
中faa
写成了cur
-
Access
没有 \(splay(p)\) -
强制在线应该
%m
却写成了%n
。(感谢机房大佬yxt的提醒)
一句忠告
不要试图在 Splay 或者 LCT 的内部使用输出调试!(这个玩意脑袋里能形成个大概的概念,但是把它们输出出来绝对不是什么好的想法)
调试 Splay 和 LCT 的最好方法是静态查错,通常看两三遍就能查出大部分错误