模模模
如此成绩,如何如何。
祂们都是怎么想到的?
A
考虑枚举一条最短边(不包含其他边的边)必选,显然这种边总存在,然后考虑剩下的边,如果某条边同时包含了必选边的两个端点,那么这条边总是合法的,否则如果要选则这条边一定包含了必选边的一个端点。
按照包含端点的不同分成两个集合 \(A, B\),现在只用考虑 \(A, B\) 之间的限制。
对于第 \(i\) 条边,记其与必选边相交的长度为 \(u_i\),剩余的长度为 \(v_i\),那么 \(A\) 与 \(B\) 之间不合法的点对 \((i, j)\) 满足 \(u_i + u_j < len, v_i + v_j < 10^6 - len\),\(len\) 是必选边长度。
把 \(A\) 中的边看作平面上的点 \((u, v)\),\(B\) 中的边看作 \((len - u, 10^6 - len - v)\),那么限制就是要求选择的 \(A\) 点不能在 \(B\) 点的左下方。
考虑选出若干 \(B\) 点,其限制构成了一个随 \(x\) 增大单调不升的轮廓线,使用线段树优化 dp 求解。
将所有点按 \(x\) 从大到小排序,从右往左进行扫描线,线段树维护 \(f_i\) 表示当前扫描线与限制轮廓线交于 \(y = i\) 时可选的最多点。
当加入一个 \(B\) 点,将 \(i > y\) 的 \(f_i\) 加 \(1\),然后令 \(f_y \gets \max_{i = 1}^y f_i + 1\)。
当加入一个 \(A\) 点,将 \(i \le y\) 的 \(f_i\) 加 \(1\)。
需要将 \(y\) 进行离散化。
B
我也不知道为什么就对了,反正暴力交上去只有 T 没有 WA,发现可以 LCT 加速,写了就过了/kk
emmm,就是直觉上肯定和 border 强相关嘛。
显然用来拼的串肯定要能匹配上前缀和后缀,所以只有 border 能成为答案嘛。
下面用 \(nxt_i\) 表示最长 border。
当 \(nxt_i \ge \frac{i}{2}\) 时肯定就可以拼出来嘛。
考虑到能拼出 \(nxt_i\) 也进而能拼出 \(i\),所以当 \(nxt_i \ge \frac{i}{2}\) 时有 \(res_i = res_{nxt_i} \oplus nxt_i\)。
然后跑大样例发现不对qwq
abaababa
这个串的 \(nxt = 3\),但是它其实能被 aba 拼出来?
我们观察,发现能用 aba 拼出 abaaba 然后能拼出 abaababa。
然后有一个思路就是你去维护每个前缀能拼出的最长长度,就是当一个串可以被拼出来时,你往上去跳 \(nxt\),更新它能拼出来的最长长度,如果当前的前缀也是能被拼出来的,你就继续往上跳继续更新。
然后查询的时候就往上跳 \(nxt\),查看是否有一个 border 能拼出来最长长度加上它本身的长度覆盖了 \(i\)。
然后写出来还是不太对,因为一个串可能不是被 \(nxt_i\) 拼出来的,是更小的 border。
然后我写了一个好像是对的但好像有没那么对的就是,直接令 \(nxt_i\) 等于能拼出它的最长 border。
然后发现这个通过了样例并且交上去足足有 88pts TLE。
emmm,更改 \(nxt\) 真的不会导致后面的 \(nxt\) 求错嘛qwq
可能不 又昔 吧。
然后发现非常方便上 LCT 就上了,这里往上跳 \(nxt\) 更新的过程由于只要连边则链上除了根都是可拼出的,所以直接 Access 到根更新就可以了。
C
等下哥们你保证了啥?
emmm
祂们都是怎么想到的?
考虑最终选出链的形式要么是直链(祖先-后代)要么是在 LCA 处拐一下的链。(废话)
然后对于直链你去树上 dfs 然后线段树合并,就维护每个深度有多少从祖先下来的链覆盖到了 \(x\)。
就是对于 \((x, y)\):\((dep_{lca}, 1) \to \operatorname{SegT}_x,(dep_{lca}, 1) \to \operatorname{SegT}_y,(dep_{lca}, -2) \to \operatorname{SegT}_{lca}\)。
然后每个点去线段树二分最浅的满足条件的祖先是什么深度。
对于拐了一下的链,先把每个给出的链放到 \(lca\) 上,然后在 \(lca\) 处,我们考虑在轻子树中枚举一个端点,然后去维护子树外满足条件的最深的点。
若我们枚举的端点是 \(x\),那么要有贡献的路径就是端点在 \(x\) 子树内的路径,然后路径的贡献在子树外的体现就是路径的另一端点到 \(lca\) 的一个链加。
注意到贡献的形式都是到 \(lca\) 的链加,所以我们其实可以在每次修改后都线段树二分一下当前最深的满足条件的点来更新维护的点。
然后枚举端点的时候要算上所有子树内的路径贡献,你就 dsu on tree 去枚举点,然后就做完了。


浙公网安备 33010602011771号