Codeforces Round #530 (Div. 1)
A
因为 (a_x geqslant 0 and forall y in son_x,s_x leqslant s_y),所以对于深度为偶数的点 (x),当 (s_x=minlimits_{y in son_x}{ s_y }) 时最优。
B
所有的合法情况要么是每行只有两种字符,要么是每列只有两种字符,枚举左上角 (2 imes 2) 矩形的情况,贪心选取即可。
C
发现分叉越多,即越接近菊花图的树,子树大小之和越小。那么可以先用完全 (k) 叉树二分出满足条件的最小的 (k),然后用一条链来构造给定的子树大小之和即可。构造时,将一个深度为 (d_1) 的叶子节点向上提到深度为 (d_2) 时,子树大小之和会减少 (d_1-d_2)。
D
先考虑怎样安排会使危险次数最多。将鱼按体重排序,每次肯定是选两个体重最小的鱼攻击最优。
称排序后满足 (a_i > 2sumlimits_{j<i} a_j) 的鱼为肥鱼,设肥鱼个数为 (cnt),将所有鱼按体重大小划分到若干组,每组内鱼的体重范围分别为 (left[2^0,2^1 ight),left[2^1,2^2 ight),dots,left[2^{29},2^{30} ight)),发现每组最多有一条肥鱼且肥鱼肯定为该组的最小值,同一组的两条鱼攻击一定会产生危险次数,不同组时其中两条鱼体重较大的为肥鱼时一定不会产生危险次数,而肥鱼的每次攻击都不会发生在同一组内,因此每条肥鱼都不会对答案有贡献,得答案为 (n-cnt)。
用 (multiset) 或者可删堆维护每组的信息即可。
E
先通过 (ST) 表求出 (b) 数组,因为 (b) 数组过大,所以只记录每个值的出现次数。二分中位数 (v),统计 (leqslant v) 的个数时可以用双指针,但是现在将 (b) 数组的连续段压到了一起,双指针时会遇到这样一个问题:当前区间最小值为 (a),出现 (A) 次,最大值为 (b),出现 (B) 次,区间 ((a,b)) 内的元素和为 (s),得其贡献为 (sumlimits_{i=1}^{A}sumlimits_{j=1}^{B}left[ia+jb+sumleqslant v ight]),设 (k=v-sum),得:
设 (f(n,a,b,c)=sumlimits_{i=0}^nmaxleft( leftlfloorfrac{ai+b}{c} ight floor,0 ight)),这个式子很像类欧几里得算法的式子,但这里不保证 (a,bgeqslant 0),分类讨论得:
若 (a<0),则 (f(n,a,b,c)=f(n,-a,b+na,c))。保证 (a geqslant 0) 后,若 (b<0),设 (d=leftlceilfrac{-b}{a} ight ceil),得 (i < d) 时都有 (leftlfloorfrac{ai+b}{c} ight floor<0),则 (f(n,a,b,c)=f(n-d,a,b+da,c))。
(a,bgeqslant 0) 后就可以去掉 (max),然后用类欧几里得算法求解即可。
F
设 (lcp(i,j)) 为 (i) 位置的后缀和 (j) 位置的后缀的 (lcp),询问 ([l,r]) 即为:
考虑用后缀树来解决,设 (p_i) 为 (i) 位置的后缀对应的节点,因为两个后缀的 (lcp) 等于其对应节点在后缀树上 (lca) 的深度,考虑在 (p_l) 的祖先统计答案,得:
这里的 (p_i in anc) 意思为 (p_i) 在 (anc) 的子树内,当 (p_i) 也在 (p_l) 祖先的子树内时,其才会产生贡献。
发现 (anc) 出现的集合为 (p_l) 到根节点深度不超过 (r-l+1) 的一条链上,称该链为 (anc) 链。发现一个节点 (x) 的贡献为其到根节点的链与 (anc) 链交的长度。
考虑树链剖分,把询问 ([l,r]) 挂到 (anc) 链的所有重链上,因为重链不一定全在 (anc) 链上,所以每条重链还要上记录 (anc) 链和重链交的长度 (L)。每个节点也挂到其到根的所有重链上,同样也在每条重链上记录重链交的长度 (len)。
先考虑第二个式子,考虑每一条中链的链顶,得:
将 ((i,len)) 看作平面上的线段,(len) 为线段长度,每个询问都是求在 (L) 和 (l-1) 限制下的线段长度和,点按 (i) 排序,询问按 (l-1) 排序后,线段树扫描线即可。
再考虑第一个式子,
未完待续
(这题代码在有了)