做题记录 25.3.19

\(\textcolor{purple}\odot\) CF1990E2 Catch the Mole(Hard Version)

考虑根号分治,令 \(B=\sqrt n\)

对于结点 \(u\),令 \(dep_u\) 表示 \(u\) 到根的距离,\(ped_u\) 表示 \(u\) 到子树内点的最大距离

找到一个 \(ped_u=B\) 的点 \(u\),对其查询

若不在其子树中,则将 \(u\) 及其子树删除,这样至少删了 \(B+1\) 个点,至多进行 \(\lfloor\frac n{B+1}\rfloor\)

否则选择任意一个叶子 \(l\),对其查询 \(B\) 次(特判在 \(l\) 的情况),此时点一定在 \(u\)\(1\) 的链上,二分即可

特判根的 \(ped\) 不超过 \(B\) 的情况

总询问次数 \(\lfloor\frac n{B+1}\rfloor+B+\log_2 n\),存在 \(\sqrt n+O(1)\) 次的算法

时间复杂度 \(O(\sum n\sqrt n)\),实现精细可到 \(O(\sum n)\)

代码

参考

\(\textcolor{blue}\odot\) CF1989E Distance to Different

显然所有同色段端点相同的 \(a\) 对应的 \(b\) 相同,因此只考虑 \(a\) 的每个同色段长度,设从左到右为 \(c_{1\sim l}\),显然必须有 \(l\ge k\)

对于一组 \(c^1_{1\sim l}\)\(c^2_{1\sim l}\),两者对应的 \(b\) 不同当且仅当 \(c^1\)\(c^2\) 中非两端的 \(2\) 替换为两个 \(1\)\(c^1\)\(c^2\) 不同

问题转化为统计满足以下条件的 \(c_{1\sim l}\) 的数量:

  1. \(l\ge k\)
  2. \(\forall 1<i<l,c_i\ne 2\)
  3. \(\sum_i c_i=n\)

\(dp\) 加前缀和优化即可,时间复杂度 \(O(nk)\)

代码

\(\textcolor{black}\odot\) CF1990F Polygonal Segments

显然一个区间合法的条件为最大值的两倍小于总和

因此考虑用线段树维护

线段树每个结点保存区间和,区间最值,区间最值位置,区间内答案(即最长合法区间的长度)

\(\text{push up}\) 时,设要合并 \([L,M]\)\((M,R]\),则令两个指针 \(l,r\) 分别为 \(L,R\),每次找到 \([l,r]\) 的最值为 \(a_p\),若区间 \([l,r]\) 满足条件则跟新答案并结束,否则若 \(p\in[L,M]\) 则令 \(l\gets p+1\),若 \(p\in(M,R]\) 则令 \(r\gets p-1\),当 \(l\le M<r\) 不成立或区间长度短于最优解时退出

显然区间只会跳 \(O(\log V)\) 次(因为每条一次最大值至少减半),因此单次 \(\text{push up}\) 时间复杂度为 \(O(\log n\log V)\)

总时间复杂度 \(O(n\log n\log V+q\log^2n\log V)\)

代码

参考

\(\textcolor{blue}\odot\) CF1988E Range Minimum Sum

令删除 \(i\) 位置后的答案为 \(f_i\),考虑每个位置对 \(f_{1\sim n}\) 的贡献

\(l_x\)\(x\) 左侧第一个 \(<a_x\) 的位置(不存在为 \(0\)),\(r_x\)\(x\) 右侧第一个 \(>a_x\) 的位置(不存在为 \(n+1\)

对于 \(1\le i<l_x\)\(r_x<i\le n\)\(f_i\),位置 \(x\) 的贡献为 \(a_x(x-l_x)(r_x-x)\)

对于 \(l_x<i<x\)\(f_i\),位置 \(x\) 的贡献为 \(a_x(x-l_x-1)(r_x-x)\)\(x<i<r_x\) 同理

两者容易通过差分 \(O(1)\) 实现

对于 \(f_{l_x}\),位置 \(x\) 对其贡献为 \(a_x(x-l'_x-1)(r_x-x)\),其中 \(l'_x\) 为删去 \(l_x\) 后的 \(l_x\),容易通过 \(\text{ST}\) 表单次 \(O(\log n)\) 求出

总时间复杂度 \(O(n\log n)\)

代码

参考

\(\textcolor{purple}\odot\) CF1987F2 Interesting Problem (Hard Version)

常规的方式为令 \(f_{l,r,i}\) 表示 \([1,l-1]\) 中操作 \(i\) 次后 \([l,r]\) 中最多操作次数,但是状态数为 \(O(n^3)\),单次转移为 \(O(n)\),难以优化,考虑化简状态

\(f_{l,r}\) 表示要消除区间 \([l,r]\)\([1,l-1]\) 中至少操作的次数

若已经得到 \(f\) 数组,要求出答案,再进行一次 \(dp\),令 \(g_i\) 表示 \([1,i]\) 最多操作的次数,则 \(g_0=0\),答案为 \(g_n\),转移为

\[g_i=\max_{L\mid f_{i-2L+1,i}\le g_{i-2L}}g_{i-2L}+L \]

考虑如何求出 \(f\)

显然长度为偶数的区间才有值

每次消除相邻的两个位置之间配对,则反映到原来的 \([l,r]\) 上为括号匹配,使用类似的方式 \(dp\)

显然 \(\frac{l-a_l}2\) 必须为整数,否则 \(dp_{l,r}\) 值不存在,令 \(v=\frac{l-a_l}2\)

拼接两对括号,则

\[dp_{l,r}\gets\min_{2\mid (k-l+1)} \max\left(v,dp_{l,k},dp_{k+1,r}-\frac{k-l+1}2\right) \]

最左侧与最右侧匹配,则

\[dp_{l,r}\gets v\;\;\;(r-l+1=2\lor dp_{l+1,r-1}\le v) \]

时间复杂度 \(O(n^3)\),常数较小

代码

参考

posted @ 2025-03-20 10:40  Hstry  阅读(7)  评论(0)    收藏  举报