20联赛集训day4 题解
A考虑对串的反串建后缀树,答案就是叶子节点个数。注意到这时的叶子节点一定是一段前缀,如果一个前缀 $s[1\ldots i]$ 是叶子节点当且仅当它不属于任何一个点的 border 集合,所以问题变成了求每个前缀的 border 集合的并的大小,用 kmp 解决即可。这里发现一个结论:每个前缀的 border 集合的并的大小等于 $\max{fail_i}$。证明要考虑这个命题等价于叶子节点...
A考虑对串的反串建后缀树,答案就是叶子节点个数。注意到这时的叶子节点一定是一段前缀,如果一个前缀 $s[1\ldots i]$ 是叶子节点当且仅当它不属于任何一个点的 border 集合,所以问题变成了求每个前缀的 border 集合的并的大小,用 kmp 解决即可。这里发现一个结论:每个前缀的 border 集合的并的大小等于 $\max{fail_i}$。证明要考虑这个命题等价于叶子节点...
A发现限制形如选了一条边之后,不能选和它端点相同的边。我们建一张新图,新图中的点代表原图中的边,如果两个边不能同时选就连边。首先可以证明问题一定有解:因为这个问题等价于对于每个弱连通分量找出一个环,而只要出度入度都为 $1$ 就一定有环,所以这种情况下更有环。我们发现原图的一种答案对应了新图的一种二分图染色方式,所以我们可以得到新图的每个连通块都是一个二分图,每个连通块有 $2$ 种染色方式...
A类似后缀数组算本质不同串的思路,考虑 $S$ 的第 $i$ 个前缀和第 $i+1$ 个前缀有多少个都会被计算,发现被算重的后缀等价于 $T$ 中 $S[i+1]$ 的出现次数。举个例子:abc abc 第 1 个前缀和第二个前缀都会算到 abc,原因是第一个前缀是 "a"+"bc",第二个是 "ab"+"c"...
A贪心删除出现次数最少的数。#include <bits/stdc++.h> #define fi first #define se second #define db double #define U unsigned #define P std::pair<int,int> #define LL long long #define pb push_back #d...
A假设 $a \geq b$树状数组分开维护就好了。#include <bits/stdc++.h> #define fi first #define se second #define db double #define U unsigned #define P std::pair<int,int> #define LL long long #define pb ...