T1
其实条件就是 \(a_i-i \le a_j-j,i-b_i \le j-b_j\),因此我们记 \(x_i=a_i-i,y_i=i-b_i\)。
显然,同一个 \(x_i\) 的点都在一个连通块内,因为它们都可以被 \(y_i\) 最大的点连起来;依照这个思路,我们记 \(mx_i\) 为 \(x=i\) 的二元组中 \(y\) 的最大值;\(mn_i\) 为 \(x \le i\) 的二元组中 \(y\) 的最小值。
那么我们按照 \(x_i\) 升序排序后,显然如果可以连边,那么一定是由 \(mx_i\) 向前连的。如果 \(\exists_{j<i} mn_j>mx_i\),那么 \(j\) 和 \(i\) 就不存在边,这就有可能形成两个连通块。因为每次判断用的是前缀最小值,因此我们的连通块在 \(x\) 上是一段区间。于是我们考虑每次新加入一个 \(mx_i\) 时,从它开始向前连边,因为可以连边的 \(y_i\) 的值域是一个前缀,所以我们就从后往前进行枚举,如果此时我们枚举到 \(k\),如果 \(mn_k \le mx_i\) 那么 \(i\) 就可以向 \(k\) 连边。
T2
赛时因为没有看清题目浪费大量时间,直接导致了没有时间进行性质观察和形成算法(很接近了)。
首先,发现只要确定了 \(s_1\),其他字符串都可以通过模拟构造。于是我们就想怎么刻画每一个字符串对 \(s_1\) 的限制。
接着,我们发现每一个字符串的限制可以表示为前 \(k\) 个字符由可重集 \(P\) 中的字符构成。
然后我们考虑一个限制 \((k,P)\) 怎么从 \(s_i\) 转移到 \(s_{i-1}\):
-
若 \(k \le |s_{i-1}|\):因为不够一个周期,所以限制仍然是对 \(k\) 个字符的。
-
若 \(k>|s_{i-1}|\):此时 \(s_{i-1}\) 在 \(k\) 中形成周期,所以我们可以加强限制,将 \(s_{i-1}\) 在 \(k\) 中的周期部分减去,只留下剩余的部分,这显然是可以 \(O(1)\) 处理的。
最后在 \(s_1\) 处统一判断限制是否合法即可。
时间复杂度分析:一个限制每次被处理至少被除 \(2\),因此至多被处理 \(\log|S|\) 次。因此时间复杂度为 \(O(n|\Sigma|\log |S|)\)。
T3
首先,两个结论:
-
最高位相同的三个数一定合法;
-
三个数 \(x,y,z\) 不合法时,满足 \(y<z\) 的充要条件是:\(y\) 和 \(z\) 的最高位相同,且 \(z\) 在 \(x\) 最高位处的值为 \(1\);(否则说明 \(y\) 在 \(x\) 最高位的值为 \(1\)。那么对于高于 \(x\) 最高位的位,\(y\) 和 \(z\) 的值相同;低于 \(x\) 最高位的位的总和也一定不会大于 \(x\) 最高位的值)
证明是显然的,观察到是困难的。
因为只有 \(n\),所以考虑 dp。
令 \(f_i\) 表示最后一个数的最高位为 \(i\) 的方案数。接下来进行分类讨论:
-
如果只取最高位为 \(i\) 的数:那么有 \(f_i \leftarrow 2^{2^i}\);
-
如果从最高位为 \(j\) 的数转移过来:那么总方案数是 \((2^{2^i} -1) \times f_j\);依据第二点进行容斥,非法方案就是在第 \(i\) 位和第 \(j\) 位都为 \(1\),其他位随意。那么我们将位数分为 \((i,j)\) 和 \((j,0)\) 两个区间,每个区间内的方案数都是一个等比数列之和,因此可以 \(O(1)\) 算出来。
上述过程处理后,得到转移:
显然可以维护前缀和,时间复杂度 \(O(n\log MOD)\)。
T4
首先,这种路径长度和点权有关的题目可以考虑将点权转化为:开一个新点,连一条边权为点权的点。
然后,这道题类似求半径(直径的一半),因为树中一个点出发的路径长度不小于直径长度的一半。
然后为了刻画一个点的路径的权值,我们将点权的转化进行两次,这样就可以刻画了(两倍点权的一半就是点权)。
经过上述转化后,树中的直径就是通常意义上的直径,那么它具有两个性质:
-
合并两棵树(包括虚树)时,新树的直径的端点一定在原来两棵树直径的四个端点中;
-
如果有一条边(一段为叶子)的边权增大,那么新的直径的端点只可能在原直径的端点、新边的叶子节点中。
利用性质一,我们有:用线段树维护当前直径中的两个端点,然后修改就直接修改,合并就利用性质。
利用性质二,我们有:我们可以用线段树分治,初始时所有点的点权都为 \(0\),操作就利用性质。
时间复杂度为 \(O(n \log^2 n)\),如果使用方法一实现加 \(O(1)\) 求 LCA,可以做到 \(O(n \log n)\)。