飘花效果

团队作业选记

全记太累了,太水的不记了,主要是蒟蒻懒

about sqrt DS

P5046 [Ynoi2019 模拟赛] Yuno loves sqrt technology I

  • 区间逆序对数模板,能支持 \(\mathcal O(n \sqrt n)\) 空间。

套路题,考虑区间查询的散 + 整 + 散,逆序对有哪些贡献。

  • 整整逆序对。
  • 散内逆序对。
  • 散整逆序对。
  • 散散逆序对。

考虑依次维护。

  • 整整逆序对直接求比较困难,记 \(ni_{i ,j}\) 为块 \([i ,j]\) 的逆序对数量,考虑递推,得到 \(ni_{i ,j} = ni_{i ,j - 1} + ni_{i + 1 ,j} + ?\),前面包含了 \([i ,j - 1]\) 的逆序对数量,后面包含了 \([i + 1 ,j]\) 的逆序对数量,发现 \([i + 1 ,j - 1]\) 的逆序对数量多算了,\(i ,j\) 两个整块的逆序对数量没算,因此 \(? = \operatorname{calc}(i ,j) - ni_{i + 1 ,j - 1}\)\(\operatorname{calc}(i ,j)\) 可以提前对块内排序然后归并解决。排序 \(\mathcal O(\frac{n}{B} \times B \log B) = \mathcal O(n \log B)\),归并 \(\mathcal O(B)\),求 \(ni_{i ,j}\) \(\mathcal O(\left(\frac{n}{B}\right)^2 \times B) = \mathcal O(\frac{n^2}{B})\),查询 \(\mathcal O(1)\)
  • 散内逆序对直接 BIT 求解即可,预处理 \(\mathcal O(n \log n)\),查询 \(\mathcal O(1)\)
  • 散整逆序对分两个,散左 + 整 / 整 + 散右。以【散左 + 整】为例,对于散左里每一个元素 \(k\),等价于计算整块内 \([1 ,k - 1]\) 的数量,用桶 \(pre_{i ,j}\) 表示前 \(i\) 个块有多少个 \([1 ,j]\) 元素即可。预处理桶 \(\mathcal O(\frac{n^2}{B})\),查询 \(\mathcal O(B)\)
  • 散散逆序对,把散左和散右分别排序然后归并即可。
    • 查询时排序,\(\mathcal O(B \log B)\),有 \(Q\) 次询问,有点不优。
    • 预处理时排序,记录每个点的下标即可。预处理 \(\mathcal O(n \log B)\)(和上面的整整一起排了),查询 \(\mathcal O(B)\)

综上,时间复杂度为 \(\mathcal O(n \log B + \frac{n^2}{B} + QB)\) 的算法,取 \(B = \sqrt{n}\) 可以做到时间 \(\mathcal O(n \sqrt n)\),空间也是 \(\mathcal O(n \sqrt n)\)

P4887 【模板】莫队二次离线 / 第十四分块(前体)

  • 莫队二离板子,没有想象的难,耐心点即可学会。

\(f([ql ,qr] ,[l ,r])\)\([ql ,qr]\)\([l ,r]\) 的贡献,莫队二离一般要快速求 \(f([x ,x] ,[1 ,x - 1])\) 以及 \(f([1 ,x] ,[l ,r])\)

第一个好求,枚举 \(x\),由 \(a_j \oplus a_i = x \Leftrightarrow a_i = x\oplus a_j\) 可以快速求解。

第二个就是所谓的第二次离线,前缀 \([1 ,x]\) 排序,由于 \([l ,r]\) 移动量是普通莫队指针移动量为 \(\mathcal O(n \sqrt n)\)(二离常识),所以可以暴力求解 \([l ,r]\)

P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II

待补。

P4168 [Violet] 蒲公英 & P13984 数列分块入门 9

  • 求区间众数模板。

仍然套路题,考虑区间查询的散 + 整 + 散,众数的所有可能。

  • 整整众数。
  • 散内众数。

考虑依次维护。

  • 整整众数依然可以 \(z_{i ,j}\) 表示块 \([i ,j]\) 的众数,显然 \(z_{i ,j}\) 可能的值为 \(z_{i ,j - 1}\) 以及【块 \(j\) 内的元素】,开个桶维护每个数出现次数,两个指针扫。预处理 \(\mathcal O(\frac{n^2}{B^2})\),查询 \(\mathcal O(1)\)
  • 散内众数,依次对散块内的每个数 \(x\) 考虑一下是否可能是答案,维护散块内每个数的出现次数 \(cnt_x\),以及整块内每个数 \(x\) 出现次数,用桶维护,和上面逆序对类似的前缀和。预处理 \(\mathcal O(\frac{n^2}{B})\),查询 \(\mathcal O(B)\),空间复杂度 \(\mathcal O(\frac{n^2}{B})\)

对于查询调用整整即为 \(z_{bl + 1 ,br - 1}\)

综上,我们有了时间复杂度 \(\mathcal O(\frac{n^2}{B} + QB)\),取 \(B = \sqrt{n}\),时间复杂度 \(\mathcal O((n + Q)\sqrt n)\),空间 \(\mathcal O(n \sqrt n)\)

P5048 [Ynoi2019 模拟赛] Yuno loves sqrt technology III

上题但是空间限制变小。

哎不对,这题不用求区间众数,只用求区间众数的出现次数!

那么我们预处理 \(z_{i ,j}\) 为块 \([i ,j]\) 众数出现次数,考虑一次查询散块元素也就 \(\mathcal O(B)\) 个,众数出现次数的取值范围为 \([ans \gets z_{bl + 1 ,br - 1} ,z_{bl + 1, br - 1} + 2B]\)

考虑依然枚举散块元素 \(x\),我们有两种方法:

  • 找到 \(x\) 最右边且不超过 \(r\) 的元素,计算中间 \(x\) 的数量和 \(ans\) 打擂台。发现用 vector 维护很好,但是要二分,多了一只 \(\log\)

  • 但是 \(ans\) 有取值范围,也就是 \(ans\) 最多增加 \(2B\) 次,只要判断从 \(x\) 开始(包括 \(x\))的第 \(ans\) 个是否在 \(r\) 前,是就 \(ans \gets ans + 1\) 即可(注意这里要用 while 哦)。

元素 \(x\)vector 里的位置要二分?实则不用,预处理 \(pos_i\) 即可,容易 \(\mathcal O(n)\)

综上,有一个 \(\mathcal O(\frac{n^2}{B^2} + QB)\) 的算法,依旧 \(B = \sqrt n\)

about STL

  • 尽量写 if(mp.count( ... )) ... mp[ ... ],否则如果 ... 位置不存在 map 会开一个 ...
  • 尽量不用 unordered_map,它不稳定。
  • 还有一些其他的……

P12763 [POI 2018 R2] 诗集 Book of poetry

显然让 \(a_i \gets (a_i + 1) \mod s\),那么题目转化为:

构造一个顺序,记 \(pre_i = \sum\limits_{k = j + 1}^i a_k \mod s\),其中 \(j\) 为上一个满足 \(pre_j = s - 1\) 的下标,如果没有 \(j = 0\),最小化 \(pre_i = s - 1\) 的数量。

考虑贪心,如果存在一个数使得 \(pre_{i} \neq s - 1\) 就填这个数,但是显然这个数不能乱填,我们考虑填剩余次数最多的那个数 \(x\)

特别地,如果 \(x\) 会使得 \(pre_{i} = s - 1\),那我们填出现次数第二多的,显然这个不会使得 \(pre_i = s - 1\)

维护每个数的出现次数以及数值,插入 set 容易维护,注意细节。

最后一个特判:去除 \(pre_n = s - 1\)

具体贪心正确性蒟蒻不会证。

P14511 [NFLSPC #8] 轨道交通

  • 总结:要大胆猜测结论。

猜测答案一定为 \(0\)

每次选择能匹配的直接匹配,如果 \([l ,r]\) 能匹配直接清空 \([l ,r]\) 的,重新匹配新的。

由于一种颜色只有 \(2\) 个端点,维护 \(fir_i ,sec_i\),那么清空操作即为 \(fir_i \gets 0\)

about 计算几何

P4293 [WC2010] 能量场

  • 拆括号,转化为几何问题。

  • 凸包 & 旋转卡壳应用。

考虑拆开计算柿子,为 \(m_ac_am_b-m_bc_bm_a\),于是令向量 \(\overrightarrow{a_i} = (m_ic_i ,m_i)\),那么贡献即为 \(\overrightarrow{a} \times \overrightarrow{b}\)

考虑第一问,转化为几何意义,叉积结果的绝对值即为向量 \(\overrightarrow{a} ,\overrightarrow{b}\) 围成的平行四边形面积,可以除以二变成三角形面积。

考虑如果叉积出来是负数,根据 \(\overrightarrow{a} \times \overrightarrow{b} = -\overrightarrow{b} \times \overrightarrow{a}\),交换两者即可,本质是叉积结果绝对值的最大值,也就是围成平行四边形的面积的最大值。

发现所求显然在凸包上,Andrew + 旋转卡壳即可。

但是要正着和反着旋转卡壳两次,因为凸包上固定向量 \(\overrightarrow{i}\),逆时针找到一个向量 \(\overrightarrow{j}\) 的叉积应该是先正从小到大,然后负从小到大,但是绝对值加了就可能是先大后小。容易发现正反两次可以避免这个问题。

考虑第二问,几何意义就是围成凸多边形的面积的最大值的两倍,凸包即可。

about 串串

不偏向计数类。

CF1320D Reachable Strings

  • 挖掘性质,寻找不变量,如奇偶、相对顺序等。

考虑一次变换会改变什么,不改变什么。

容易发现中间的 1 不变,好像没用;旁边的 0..1 交换位置。

发现只有一个 \(0\),且交换后 0 的奇偶位置不变。

显然/手玩会发现 0 的相对位置不变。

因此题意转化为:

给定两个以 \(l_1 ,l_2\) 开头的字符串,判断 \(0\) 的个数是否相同,并且每个 \(0\) 的出现位置奇偶性是否相同,分别以 \(l_1 ,l_2\) 为初始下标(即为 \(1\))。

手玩一下发现是对的,严谨证明略,感觉略微显然。

然后这个可以对 \(0\) 的位置奇偶性进行 hash,奇数为 \(1 + x\),偶数为 \(0 + x\)\(x\) 是我们定义的常数,用来减小冲突(其实 \(x = 0\) 也可以)。

我们定 \(has_{i ,0/1}\) 为起点是偶/奇时的 hash 值,对于 \(2\mid i\) 的位置 \(i\) 能对 \(h_{i ,0}\) 产生贡献,对于 $2\nmid i $ 的位置 \(i\) 能对 \(h_{i ,1}\) 产生贡献。

然后用区间 hash 判断一下每组询问,这题就做完了。

AT_arc151_e [ARC151E] Keep Being Substring

  • 分类讨论和图论建模,包括样例也很重要。

下文把数当成字符。

手玩两个样例,第一个样例有解释,我们发现如果 \(x ,y\) 存在公共子串,设长度为 \(k\),那么可以把 \(x\) 删到只留下这个长 \(k\) 的子串,然后添加 \(y\) 中的非该子串的字符。

最少需要为 \(\lvert x\rvert + \lvert y \rvert - 2k\),这是显然的,也容易证明每一步都合法。我们需要最大的 \(k\)\(k_{max}\),即求两个字符串的最长公共子串,Hash + 二分/SAM 均可。

如果 \(k_{max} = 0\),考虑我们刚才的做法是先删后加,这样会把 \(x\) 清空,不合法。

一种思路是把 \(x\) 加到存在和 \(y\) 有公共子串的时候再删和加,容易发现长度为 \(1\) 必然不劣。

由于最后我们要删除 \(\lvert x \rvert - 1\) 个字符,留下这个共有字符,我们不妨先删除 \(x\) 到只有一个字符,这样左边右边都能扩展,肯定不劣于刚才的做法。

也即是说我们要对于 \(x\) 中的每一个字符 \(b\),找到一个属于 \(y\) 中的字符 \(c\)(添加操作),然后删除除了 \(c\) 的字符,最后添加 \(y\) 中非 \(c\) 字符。

假设离 \(b\) 左边或者右边最近的字符 \(c\)\(b\) 的距离为 \(k\),那么显然要 \(\lvert x \rvert - 1 + k + k + \lvert y \rvert - 1 = \lvert x \rvert + \lvert y \rvert + 2k - 2\) 步。

容易发现添加只关系到相邻的字符,我们对 \(a_i \xrightarrow{cost = 1} a_{i + 1}\) 建图,那么等价于一个多源 dij 问题。

然后我们找到最小的 \(d\),答案即为 \(\lvert x \rvert + \lvert y \rvert + 2d - 2\)

由于 \(d\ge 1\),所以这种方法劣于存在公共子串的方法,因此做法不存在问题。

CF1080E Sonya and Matrix Beauty

  • trick:子矩阵计数可以考虑枚举左右界拍扁成 \(n\)\(r - l + 1\) 列,然后用什么线性/单 log 的算法计数。

本题就是这样。

先不考虑列,考虑行怎么样,行能重排成回文当且仅当:

  • 列长为偶数,每个字符出现次数都是偶数。
  • 列长为奇数,每个字符出现次数最多只有一个奇数。

然后考虑列,假设拍扁的矩阵只有 \(k\) 行。

  • 如果我们排完了第 \(1\) 行,那么第 \(k\) 行必须和第 \(1\) 行相等。
  • 如果我们排完了第 \(2\) 行,那么第 \(k -1\) 行必须和第 \(2\) 行相等。
  • ……

也就是这些对应行的【字符出现次数数组】必须相同,直接 hash 即可。

然后就是回文问题,manacher 即可。

注意如果不合法需要断开,但是我们有更简单的方法,直接将 hash 值赋值成互不相同的不在 \([0 ,mod - 1]\) 内的整数即可实现断开。

about constructive algorithms

构造水平一坨。

常用 trick:

  • 弱化限制。
  • 强化限制。
  • 特殊性质。
  • 答案上下界。
  • 外围排除法。
  • 等等。

CF1485D Multiples and Power Differences

考虑弱化限制,没有 \(a_{i ,j} \mid b_{i ,j} ,b_{i ,j} \ge 1\) 的限制。

对于网格图,黑白染色是个常见的思路。

于是可以构造:

\[b_{i ,j} = \begin{cases} 1 & (i + j) \bmod 2 = 1 \\ 0 & (i + j) \bmod 2 = 0\end{cases} \]

考虑加上 \(a_{i ,j} \mid b_{i ,j}\) 的限制(令 \(a \mid 0\)),可以构造:

\[b_{i ,j} = \begin{cases} a_{i ,j}^4 & (i + j) \bmod 2 = 1 \\ 0 & (i + j) \bmod 2 = 0\end{cases} \]

考虑加上 \(b_{i ,j} \ge 0\) 的限制,我们只要加上一个数 \(c = \operatorname{lcm}(1 ,2 ,3 ,\dots ,15 ,16)\) 即可,即:

\[b_{i ,j} = \begin{cases} a_{i ,j}^4 + c & (i + j) \bmod 2 = 1 \\ c & (i + j) \bmod 2 = 0\end{cases} \]

正确性显然。

CF1667C Half Queen Cover

发现是构造最优解,考虑答案下界,并尝试构造到答案下界。

令最少摆放 \(k\) 个半皇后,先不考虑对角线,钦定它们放在前 \(k\) 行前 \(k\) 列,因为完全可以平移格子。

考虑上对角线,那么剩下的右下角 \((n - k) \times (n - k)\) 只有可能被对角线先覆盖。

\((n - k) \times (n - k)\) 的棋盘有 \(2(n - k) - 1\) 条对角线,因此满足 \(k\ge 2(n - k) - 1\),解得 $k \ge \lceil \frac{2n - 1}{3} \rceil = \lfloor \frac{2n + 1}{3} \rfloor $。

考虑构造,在 \((1 ,1)\) 放置一个半皇后,然后第二行可以放在 \((2 ,3)\),放 \((2 ,2)\) 肯定不优,两者覆盖了右下角棋盘的同一个对角线。

当列 \(> k\) 时把列改为 \(2\),然后 $4 ,6 ,8\dots $ 即可。

可以证明这是正确的,数量恰好为下界(右下角棋盘的对角线仅被一个半皇后覆盖)。

CF1158B The minimal unique substring

注意力?

考虑加强限制,猜测存在构造方案是一个无 border 串不断循环(可以不是整循环)。

注意力惊人,想到这个可能是发现样例有循环节,然后弱化一下循环节无 border。

假设循环节长度为 \(p\),对于最短唯一子串的长度恰好为 \(k\),等价于:对于长 \(i \in [1 ,k - 1]\) 所有子串并非唯一子串,但是对于长 \(k\) 的子串存在唯一子串。

由于循环串无 border,那么对于一个长度为 $j < k $ 的子串,只能通过位移 \(\pm p\) 位得到另一个相同的子串。

  • \(j < k\):对于所有子串的起始位置 \(i\),都有 \(i - p \ge 1\) 或者 \(i + p - 1 + j \le n\),即 $ p \le \max (i - 1 ,n - i - j + 1 \ge n - i + 1 - (k - 1) = n - i - k + 2 )$。当 \(i - 1 = n - i - k + 2\) 限制最紧,\(i = \frac{n - k + 3}{2}\),但是此时 \(i\) 不为整数,故 \(i = \frac{n - k + 2}{2}\),代入得到 \(p \le \frac{n - k + 2}{2} ,2p \le n - k + 2\)
  • \(j = k\):只要存在 \(i\) 使得 \(i - p < 1\) 并且 \(i + k - 1 + p > n\) 即可,得 \(\max\{i - 1 ,n - i - k + 1\}< p\),由于存在只要有一个满足要求的 \(p\) 即可,限制最宽 \(i - 1 = n - i - k + 1 ,i = \frac{n - k + 2}{2}\),代入得 \(p > \frac{n - k}{2} ,2p > n - k\)

因此 \(p = \frac{n - k + 2}{2}\),然后只要构造一个长它的无 border 串然后循环即可。

AT_agc064_b [AGC064B] Red and Blue Spanning Tree

比较显然的构造,但我还是不会/ll。

对于一条边 \((u ,v ,w)\) 满足 \(a_u = w ,a_v = w\) 的边,我们一次可以满足两个端点的要求,贪心地就选上。

然后是对于一条边 \((u ,v ,w)\) 满足 \(a_u = w\)\(a_v = w\),一次可以满足一个端点的要求,贪心地选上。注意这里选边应该是从第一类选上的节点开始,BFS 添加,否则不能保证你随便添加的是基于当前情况下优秀的。

最后把剩下的选上,就是凑齐树边。

如果最后还是不能使所有端点都满足条件,或者图不连通,那么输出 No

posted @ 2026-04-07 10:11  2021zjhs005  阅读(8)  评论(0)    收藏  举报