记一场暑期最低分的模拟赛
RT,\(100 + 0 + 75 + 10 = 185\),\(75\) 是反向挂分,数据太水,\(0\) 是最后四分钟调试不出发现做法假了来不及打暴力。
CF896A Nephren gives a riddle
递归板板题,一开始被吓坏了,回来看时发现太板。
你会发现长度增加很快,于是做完了。
不想写递归写了个 while 喵。
CF1968G2 Division + LCP (hard version)
喵喵昨天讲了根号分治今天硬是没想到。
一开始想了个转化,\(\mathcal O(n^2)\),然后是唐诗 DP,假了。
显然的是,如果某个前缀在字符串中不重叠出现至少 \(k\) 次,那么其能划分成 \(k\) 段并满足题意。
如果直接去计算是 \(\mathcal O(n^2)\) 的。
有部分分 \(l = r\)(CF1968G1),考虑 \(l = r\) 怎么做,这个前缀如果长的不能划分 \(k\) 段更长的必然不可行,因此二分答案,Hash / KMP 写 check,时间复杂度 \(\mathcal O(n \log n)\)。
对于多个 \(k\),每个都二分一遍,复杂度 \(\mathcal O(n^2 \log n)\)。
有个容易想到的是 \(f(k) \le \frac{n}{k}\),考虑根号分治,当 \(k < \sqrt n\) 时如上做法,复杂度 \(\mathcal O(n \log n \sqrt n)\),考虑 \(k > \sqrt{n}\)。
此时 \(f(k) < \sqrt n\),因此可能贡献前缀长度最大 \(\sqrt n\),暴力匹配,复杂度 \(\mathcal O(n \sqrt n)\)。
注意控制二分上界 \(\lfloor \frac{n}{i}\rfloor\) 可以节省一定时间,用一个数字记录二分过的数的答案可以节省相当多的时间,双 Hash 可能 TLE 用优秀的单 Hash(不如 KMP)等。
xyz dsa 说他用了 Z 函数喵 /bx/bx/bx/bx/bx,喵呜就是优化 \(\mathcal O(n^2)\) 做法,仍然枚举前缀 \([1 ,k]\),能匹配等价于 \(z_i \ge k\),瓶颈在于匹配不了要 \(+1\) 跳,显然拿个 ST 表二分即可,TJ 从小到大枚举 \(k\) 说可以用 DSU 喵,也是 DSU 作链表的一个小 trick 喵。
机房 cjx dsa 用了 SA 喵 /bx/bx/bx/bx/bx,被 dddl 了/ll,蒟蒻 SA 早就忘光了。
CF506D Mr. Kitayuta's Colorful Graph
喵呜又是根号分治。
容易把题目转化为只保留同种颜色的边,判断两点是否同一个连通块。
考虑部分分【颜色数量最多 \(200\)】,每个颜色并查集维护,暴力所有询问,复杂度 \(\mathcal O(col \times ( m \alpha + n + Q ))\)。
考虑颜色数量很多喵,那么相同颜色的边肯定很少,直接记录下来所有点,假设有 \(s\) 个(记得去重哦),\(\mathcal O(s^2)\) 暴力枚举所有点对增加贡献(用 map 只记录 \(x < y\),否则一直 MLE 喵)。
找个值域 \(B = \sqrt n\) 平衡一下即可喵。
CF997E Good Subsegments
喵喵我说怎么这么熟悉原来我做过这题的弱化版但是考试时不会喵,原因是昨天讲分治写了个启发式分裂发现两边都要计算成功假部分分喵。
考虑弱化版,全局询问,不考虑分治,这类题目有个套路是固定右端点 \(r\) 计数,即对于每个 \(r\) 求有多少个 \(l\) 使得 \(mx[l \dots r] - mn[l \dots r] = r - l\),整理得 \(mx - mn + l - r = 0\)。
考虑用 SGT,每个叶子维护 \(mx - mn + l - r\),查询即为询问区间为 \(0\) 的数量,显然它 \(\ge 0\),转化为求最小值(必须为 \(0\))的出现次数。
当 \(r \gets r + 1\) 时,全局减 \(1\)。
考虑 \(mx\) 和 \(mn\) 对这个式子的贡献影响,影响范围是左边第一个比 \(a_i\) 小/大(开)到 \(i\)(闭)这一段,用单调栈维护,贡献偏移量容易计算。
于是你通过了 \(q \le 5 ,n \le 2\times 10^5\)。
考虑多次询问区间怎么做,显然把询问右端点放一起离线做,问题转化为对每一组 \([l ,r]\) 求 \([l ,r]\) 内有多少个 \(0\)。
看着一样的喵,但是你发现 \(l\) 在变化不能用变量记录,直接问得到的是右端点为 \(r\) 的答案。
因此转化为求每个点 \(l' \in [l ,r]\) 在所有历史版本(右端点 \(r' \in [1 ,r] ,l' \le r'\))的贡献值和,也就是区间历史贡献之和。
每次在修改完新的右端点 \(r\) 时要对 \([1 ,r]\) 所有 \(0\) 增加历史贡献。
然后维护一个历史区间懒标记加法和历史区间贡献总和,对历史和贡献为 \(hisadd \times cnt\)(\(cnt\) 为区间最小值 \(0\) 的出现次数),其余懒标记下传类似。
你会发现 queryhis 返回没有判断 Min[u] = 0,当前不为 \(0\) 没关系历史可能为 \(0\) 喵。
本文来自博客园,作者:2021zjhs005,转载请注明原文链接:https://www.cnblogs.com/2021zjhs005/p/22135274

浙公网安备 33010602011771号