题目乱做笔记 Part2
CF1824D
考虑如何快速计算 \(g(i,j)\),设 \(nxt_i\) 表示 \(i\) 后面第一个等于 \(i\) 的数,那答案显然是最大的 \(p\) 满足不存在 \(k \in [i,p-1],nxt_k>j\)。
从大到小扫描 \(i\) 这一维,问题变成区间覆盖,区间求历史最值和,显然可以直接上线段树,但是需要卡常。
同时也可以使用颜色段均摊将区间覆盖转化成区间加,这样会难写一些,不过无需卡常。
CF1552G
首先需要发现一个结论:对于所有序列合法等价于对于所有 \(\verb!01!\) 序列合法。
证明:对于所有序列,考虑将 \(\le x\) 的数设为 \(0\),\(>x\) 的数设为 \(1\),那么若 \(x\) 取遍所有值生成的 \(\verb!01!\) 序列均合法,原序列显然合法。
但是现在依然只能做到 \(\Theta(2^n)\) 的复杂度,考虑优化。
优化的思路是当我使用过第 \(i\) 次操作后,被第 \(i\) 次操作包含的那些位置一定是前面一些 \(0\),后面一些 \(1\)。
那么考虑对操作搜索,若一个位置还没有被操作覆盖,我们设它为 \(\verb!?!\),那么对于当前搜到的操作,它包含的位置一定是一些 \(\verb!0/1!\) 和一些 \(\verb!?!\),注意到 \(\verb!0/1!\) 是在之前的枚举中确定的,而 \(\verb!?!\) 我们只关心它们之间有几个 \(\verb!0!\) 几个 \(\verb!1!\),那么复杂度就是每层的 \(\verb!?!\) 个数乘积,显然是 \(\Theta((\dfrac{n}{k}+1)^k)\)
「GLR-R3」清明
模拟赛题,但是我不会。
快进到正解部分。
设 \(c_{i,j}\) 表示 \(i\) 分配给 \(i+j\) 的雨滴数,可以写出答案:
我们可以将 \(\prod \sum\) 展开,这样就变成了 \(\sum\) 若干个 \(n\) 项式。
显然我们可以考虑每个 \(n\) 项式的贡献,然后求和。
假设我们当前考虑的 \(n\) 项式为 \(\prod \prod_{j \in S_i} c_{i,j}\)。
考虑加入这个式子的出现次数,出现次数自然是 \(\sum [\sum_j c_{i,j}=a_i]\)。
写出总式:
考虑固定所有 \(S_i\),如何计算答案。
设 \(r_i=\min(k+1,n-i+1)\),考虑组合意义。
发现原式等价于:将 \(a_i\) 分成 \(r_i\) 份,有 \(|S_i|\) 份是放了多少答案乘多少,另外的不管放多少,都对答案没有影响,问所有方案的答案之和。
列出生成函数:\(\dfrac{1}{(1-x)^{r_i-|S_i|}} \times (\dfrac{x}{(1-x)^2})^{|S_i|}=\dfrac{x^{|S_i|}}{(1-x)^{r_i+|S_i|}}\),我们要求的便是第 \(a_i\) 项系数。
发现这个生成函数的组合意义就是求方程 \(x_1+x_2+...+x_{r_i+|S_i|}=a_i-|S_i|\) 的非负整数解个数,于是直接插板可得到答案为 \(\dbinom{a_i+r_i-1}{r_i+|S_i|-1}\)。
进一步的,由上式可以发现,我们不关心 \(S_i\) 具体是啥,只关心 \(|S_i|\)。
于是考虑 DP 计数,继续观察,发现每个 \(i\) 的 \(|S_i|\) 可以从 \(j \in [i,i+r_i-1]\) 中取,同时每个 \(j\) 只能被取一次,因此状压配合高维前缀和即能轻松做到 \(\Theta(2^k \text{poly}(n)\text{poly}(k))\)。
显然这无法通过,考虑按 \(k\) 分治,当 \(k\) 很大的时候 \(n-k\) 很小,考虑枚举后面部分后进行容斥,前面跑一个类似 subtask6 的 \(\Theta(\text{poly}(n))\) 的 DP 即可。
「GLR-R4」夏至
考虑 \(n=1\) 怎么做。
使用 Powerful Number 筛,具体地,考虑构造数论函数 \(g,h\) 满足对于素数 \(p\),\(g(p)=f(p)\),并且 \(g*h=f\)。
进一步,由于 \(h\) 是积性函数,所以 \(h\) 仅在 Powerful Number 处有值。
并且,\(n\) 以内的 Powerful Number 个数可以通过积分证明是 \(\Theta(n)\) 级别的。
尝试写出 \(f\) 的前缀和:
由于 \(h\) 有值的位置很少,考虑将 \(h\) 移到前面,得到:
因此直接暴搜 Powerful Number 并求值即可,\(h\) 函数以及 \(G\) 函数的前缀和都是不难求的。
简单记录一下如何求 \(h(p^k)\),暴力展开得到 \(f(p^k)=\sum_{i=0}^k g(p^i)h(p^{k-i})\),\(h(p^k)=f(p^k)-\sum_{i=1}^{k} g(p^i)h(p^{k-i})\)。
考虑怎么做 \(n>1\),由于 \(n\) 比较小,因此记 \(F(x,m)=\sum_{i=1}^x f(im)\),枚举 \(x\) 计算 \(F(x,m)\)。
考虑递归计算,设 \(x\) 的最大质因子为 \(p\),考虑消去 \(x\) 中的所有 \(p\),设消去后 \(x\) 变成了 \(x'\),\(x=p^cx'\),那么,枚举 \(1 \le i \le m\) 中 \(i\) 有几个 \(p\),不妨设为 \(i\) 个,容斥一下,将至少有 \(i\) 个的方案数减去至少有 \(i+1\) 个的方案数即可,通过观察官方题解得知,直接模拟的复杂度是正确的。
CF1381D
考虑什么地方蛇可以掉头,不难发现这个点必须有至少三条长度 \(\ge len\) 的不相交链,其中 \(len\) 是蛇包含的点数。
不妨称这些点为关键点,那么若蛇头能走到某个关键点,必然合法,若走不到任何关键点,必然不合法。
结论:若蛇头能到达某个关键点,必然能到达所有关键点。
证明:显然。
因此我们取出任意关键点 \(r\),判断蛇头能否走到 \(r\) 即可。
将 \(r\) 设为根,设蛇头为 \(A\),蛇尾为 \(B\),那么如果 \(A,B\) 存在祖先关系,那必然合法,否则设 \(C=\text{LCA}(A,B)\),那在 \(A,B\) 存在祖先关系之前,它们的 \(\rm LCA\) 一定是 \(r\)。
设对蛇头的操作是 \(\verb!L!\),对蛇尾的操作是 \(\verb!R!\)。
那答案序列便是 \(\verb!LLL...LRRRR...RLLL...LRRRR...R!\)。
考虑某个连续段 \((l,r,v)\),不难发现这个连续段令蛇头增添的深度可以在下一个连续段中消掉,那显然每个连续段里都移动到最深处是最优的,于是直接模拟过程即可,具体地,维护两个指针 \(A\) 和 \(B\),每次把 \(A\) 移动到 \(A\) 子树内最深的叶子或把 \(B\) 移动到 \(B\) 子树内最深的叶子,注意若出现了循环则输出无解,否则 \(\max(\text{dep}(A),\text{dep}(B))\) 必然单调递增,因此复杂度正确。
CF573D
将 \(w\) 和 \(h\) 都排序,最优方案显然是 \(w_i\) 与 \(h_i\) 匹配。
不过有可能匹配不了,通过画图得知与 \(w_i\) 匹配的 \(h_j\) 必须满足 \(j \in [i-2,i+2]\)。
于是直接 DP 即可,需要加上矩乘加速。
CF1558E
第一步是二分答案。
二分完之后如果没有不能走回去的限制直接维护一个 \(\verb!priority_queue!\) 每次扩展 \(a\) 最小的点就行了。
考虑加上限制怎么做。
我们自然想让每次扩展都是“没有后效性”的,也就是扩展之后能走到的点完全包含扩展之前能走到的点,如果这个成立,那每次能扩展就扩展便是正确的。
为了达成这个目的,我们可以每次扩展一个 \(ρ\) 形,其中 \(ρ\) 形链处的部分存在已扩展点,并且从已扩展点开始走能够扩展所有点。
由于保证了每个点度数 \(\ge 2\),因此若能扩展,每次都能扩展 \(ρ\) 形。
考虑如何寻找 \(ρ\) 形,乍一看没有什么多项式复杂度做法,但事实上,我们从 \(ρ\) 形链处的已扩展点开始暴搜,若存在一个点被访问两次,如果这两条路径在已扩展点外有交,那将这个点回退,否则已经找到了一个 \(ρ\) 形。
于是直接模拟即可,时间复杂度 \(\Theta(nm\log a_i)\)。
CF771E
首先考虑暴力 DP,设 \(f_{i,j}\) 表示第一行扩展到第 \(i\) 列,第二行扩展到第 \(j\) 列的答案,可以直接转移。
这样显然是过不去的,考虑减少状态数。
对于任意一种方案,我们将矩形按照左端点坐标为第一关键字,行坐标为第二关键字排序。
对于某个 \(f_{i,j}>f_{i,i}+1\),我们将说明状态 \(f_{i,j}\) 能够舍去,具体地,因为 \(f_{i,j}>f_{i,i}+1\),因此 \([i+1,j]\) 区间中一定放着 \(\ge 2\) 个矩形,设第一个矩形覆盖的列为 \([p,q]\),第二个矩形为 \([P,Q]\),若最终答案中另一行的 \([i+1,Q]\) 区间存在矩形,那 \(f_{i,j}\) 显然直接被舍去,否则可以从 \(f_{i,q}\) 转移到 \(f_{q,q}\) 然后转移到 \(f_{Q,Q}\),\(f_{i,j}\) 也是没用的。
同时我们也发现对于 \(f_{i,j}=f_{i,i}+1\) 和 \(f_{j,i}=f_{i,i}+1\) 的 \(j\),我们仅需保留最小的两个 \(j\)。
因此对于每个 \(i\),我们只需记录三个状态,直接转移即可。
时间复杂度 \(\Theta(n)\)(若使用哈希表寻找矩形)。
CF1175G
转移 \(k\) 层,每层的转移形如 \(f_i=\min(g_{j-1}+(i-j+1) \times (\max_{k \in [i,j]} a_k))\)。
考虑分治优化转移,每次考虑跨过中点的区间,分类讨论最大值在左边或是右边的情况。
分讨之后转化成动态加直线,动态维护某个位置最值,同时查询的位置是单调的,只需记录一个单调栈即可。
CF1801E
我们发现有用的合并只会发生 \(\Theta(n)\) 次,考虑令每一次合并都是有用的。
这是简单的,树状树组维护链上哈希值,然后二分一下即可。
CF698F
考虑 \(a_i\) 全 \(0\) 怎么做。
由于排列 \(p_i=i\) 一定合法,我们考虑从排列 \(p\) 推出所有合法排列。
考虑什么情况下 \(i,j\) 能够交换:
- \(i\) 和 \(j\) 包含的质因子集合相同。
- 对于两个质数 \(p,q\),若 \(\lfloor \dfrac{n}{p} \rfloor=\lfloor \dfrac{n}{q} \rfloor\),那么可以把所有 \(p\) 的倍数和 \(q\) 的倍数整体按原顺序交换。
首先满足这两种情况一定是能够交换的充分条件,但为啥是必要的我并不知道。
假装这是对的,考虑存在 \(a_i\) 非零怎么做。
如果 \(i\) 和 \(a_i\) 的质因子集合大小不同,那显然无解。
接着考虑如果 \(p,q\) 满足 \(\lfloor \dfrac{n}{p} \rfloor=\lfloor \dfrac{n}{q} \rfloor\),那必然有 \(p,q \ge \sqrt n\)。
因此我们直接取出 \(i\) 和 \(a_i\) 的最大质因子,判断一下映射关系即可。
CF1299D
看到非简单回路的异或和,容易想到线性基。
注意到值域非常小,进一步,发现大小为 \(5\) 的线性基只有 \(374\) 种可能。
因此考虑将线性基记入状态中,做一个 DP。
把点 \(1\) 删掉之后给每个连通块赋予一个编号,按编号从小往大 DP。
不难发现 \(1\) 与每个连通块最多连两条边,于是可以把连通块分类:与 \(1\) 连一条边和与 \(1\) 连两条边。
与 \(1\) 连一条边的连通块有两种决策:不选/把这个连通块的线性基与当前线性基直接合并。
与 \(1\) 连两条边的连通块有三种决策:不选/把这个连通块的线性基与当前线性基直接合并/在合并的基础上加上长度为 \(3\) 的环。
于是直接 DP 即可,预处理一下线性基的合并结果,注意若一个元素无法加入线性基那一定非法。
CF1178G
难绷,KTT 板题。
发现这个 \(b_i\) 一点用都没有,是来诈骗的。
按 DFS 序拍平成序列后问题变成每次区间加 \(a_i\),询问区间 \(|a_i| \times b_i\) 的最大值。
把绝对值消掉之后就变成 KTT 板子了。
CF1583G
我们称一个区间被“彻底点亮”当且仅当它之后不会被熄灭。
那么区间被“彻底点亮”的顺序肯定是按 \(a_i\) 从小到大。
假设区间已经按 \(a_i\) 从小到大排好序了。
那么当 \(i\) 被“彻底点亮”时一定满足 \(1 \sim i-1\) 已经被“彻底点亮”,并且 \(i+1 \sim n\) 均熄灭。
设 \(f_i\) 表示当前 \(i\) 左边的区间已经被“彻底点亮”了,\(i\) 右边的区间均熄灭,想要让 \(i\) 被“彻底点亮”的操作次数。
不难发现为了从 \(a_i\) 走到 \(b_i\),右端点在 \((a_i,b_i)\) 的所有区间必须都被点亮,由于 \(a_j<a_i\) 的区间 \(j\) 已经被点亮,因此需要的操作次数为 \(\sum_{j=i+1}^n [b_j<b_i] \times f_j\),然后再加上点亮区间 \(i\) 的一次操作就能得到转移式。
接下来考虑统计答案,也是一样的道理,如果存在一个 \(j \in S\) 满足 \(i<j\) 且 \(b_i<b_j\),那么 \(i\) 必须被点亮。
CF264E
最关键的性质是 \(h_i \le 10\) 和 \(x_i \le 10\)。
注意到题目里树每天变高等价于令当天的 \(h_i\) 减去当前天数后树高不变。
同时由于 \(h_i \le 10\) 并且不存在两颗树树高相同,因此比当前树低的树最多只有 \(9\) 颗。
因此在添加的时候可以暴力找出这些树,然后用线段树维护一下 DP 值。
又因为 \(x_i \le 10\),因此在修改的时候也可以暴力找出这些树,用线段树维护一下 DP 值。
具体的,只需维护下标的线段树和值域的线段树即可。
CF1854E
很难绷的乱搞题。
从小往大加数,给每个数一个限制,表示最多加几个,这个限制在 \([5,6]\) 里面随机,然后能加就加,然后就过了。
CF533A
首先考虑如何 \(\Theta(n^2)\)。
我们一开始将所有点到根的权值 \(\min\) 按从大到小的顺序排序,将目标权值集合按从大到小的顺序排序,一个一个匹配过去,如果在匹配到 \(i\) 的时候寄了,意味着 \(i\) 需要匹配的 \(x\) 必须满足 \(1 \sim x\) 的链上有点修改过。
枚举 \(i\) 匹配哪个 \(x\),然后计算一下要使 \(i\) 能匹配 \(x\) 需要在哪个点增加多少的权值,增加完权值后再跑一遍之前说的贪心(注意这个点一定不会增加更多的权值了),判断一下是否合法即可。
考虑优化这个暴力,直接优化贪心的过程显然是没有前途的,考虑一步转化:原问题合法当且仅当 \(i\) 能匹配的点的个数 \(\ge i\)。
因此我们可以开一颗线段树,设 \(p_i\) 表示 \(i\) 能匹配的点的个数,我们只需维护 \(p_i-i\) 的最小值即可。
考虑我们增加完权值会对哪些点造成影响,不难发现某个点能影响的那个点必须满足这个点是那个点到根路径上的最小值,并且是唯一的最小值。
因此我们只需暴力修改所有需要修改的点,时间复杂度均摊 \(\Theta(n \log n)\)。
CF436F
稍微转化一下问题可以转化成区间加等差数列,求全局 \(\max\),直接用 KTT 维护即可。
CF1609G
注意到由于差分数组单调,因此最优决策是每次选小的那一边。
等价于把差分数组归并排序之后每个位置有 \(n-i+1\) 的贡献。
由于 \(n\) 只有 \(100\),因此直接暴力枚举 \(a\) 的差分数组,在 \(b\) 的差分数组上维护一颗线段树,每次线段树上二分找到两个 \(a\) 中间插入几个 \(b\),同时再维护一些区间和之类的东西就能算贡献了。
CF461E
不清楚字符集为啥要开这么小,开成 \(100\) 同样能做。
考虑如何计算一个字符串被拼成的最小操作次数,从左往右扫一遍,如果上一个字符所在的连续段加上当前字符仍然是 \(t\) 的一个子串,那就直接加入,否则新开一个连续段,不难证明这是正确的。
那么把 SAM 建出来之后我们可以据此设计一个 \(\Theta(n|t|)\) 的 DP,具体地说就是设 \(dp_{i,j}\) 表示前 \(i\) 个字符,当前最后的连续段对应了 SAM 上的节点 \(j\) 的最大操作次数。
这显然是过不去的,注意到对于固定的 \(t\),\(n=x+1\) 时的答案一定大于等于 \(n=x\) 时的答案。
同样的,当答案为 \(x\) 时对应的最小 \(n\) 也一定小于等于答案为 \(x+1\) 时对应的最小 \(n\)。
因此我们可以二分答案,现在问题变成计算答案为 \(x\) 时的最小长度。
若 SAM 上节点 \(x\) 没有连向字符 \(c\) 的边,那么我们令 \(x\) 连向字符 \(c\) 的边到达的点为根节点连向字符 \(c\) 的边到达的点,我们尝试把这个问题写得更清楚一点:
给你一张有向图,满足上面有 \(4\) 个特殊点。
你有两个变量,\(cnt1\) 和 \(cnt2\)。
你从根开始走,每经过一条边则 \(cnt1\) 加一,每到达一个特殊点则 \(cnt2\) 加一,当 \(cnt2\) 为 \(x\) 时过程终止。
你可以任意安排你走的路径,需要求出终止时 \(cnt1\) 的最小值。
设 \(cnt2\) 在点 \(a_1,a_2,\dots,a_n\) 上加一,不难发现 \((a_i,a_{i+1})\) 的种类只有 \(16\) 种。
因此暴力求出每种 \((a_i,a_{i+1})\) 经过的最少边数,然后矩阵快速幂转移即可。
CF788D
考虑询问 \((a,a)\),如果答案是 \(0\),那说明要么有直线 \(y=a\),要么有直线 \(x=a\),要么两条都有。
如果答案不是 \(0\),是 \(D\),那我们至少可以确定 \([a-D+1,a+D-1]\) 这个区间里没有任何直线。
按照这个分治下去即可。
由于一次询问至少确定一条直线,同时也不会产生很多无用区间,所以能过。
CF1776M
比较抽象的做法,我也不知道它对不对,很可能是假的,如果有 dalao 能证明或者 hack 请私信我。
首先考虑二分答案,把 \(\ge mid\) 的点设为黑点,\(<mid\) 的点设为白点,那问题变成后手是否能令先手选不到任何一个黑点。
猜测先后手的策略,我们把当前能选的点分成三类:
- 黑点
- 白点,并且删掉它之后会出现一个能选的黑点
- 白点,并且删掉它之后不会出现能选的黑点
首先如果存在黑点,不管是先手还是后手都一定会直接选掉。
如果不存在黑点,我们优先删去第三类点,否则再删第二类点,因为如果后手删了第二类点,会立即输掉,如果先手删了第二类点后手会立即删掉新出现的能选的黑点,相当于平白无故少了一个黑点,感觉并不是很优。
如果直接按照这个东西写,会获得 Wa on test 14,然后我用一个 pair 表示第二类点,并优先取删掉这个点后对应的那个黑点标号比较大的,然后它过了???
代码就是直接照着这个模拟,是两只 \(\log\) 的。
CF297E
太牛了。
可以先画出所有可能情况,一共有五种,不难发现其中两种是合法的。

对于这两种合法的情况,我们可以列出一些式子表示这些情况的限制,一般的思路是直接对着这些式子上数据结构优化。
但是这样是没有前途的,你会发现这东西根本优化不了。
这个时候需要想到容斥,我们先预处理出 \(l_i,r_i\) 表示在 \(i\) 左边和 \(i\) 不相交的弦的数量,\(r_i\) 表示右边的。
然后可以进一步发现非法情况可以分成两类:一类是 \(\verb!Type 1!\),这种情况的计算是简单的,是 \(\sum l_i \times r_i\);另一类是 \(\verb!Type 3/4!\),我们发现它们的共性是都恰好存在两条弦满足剩下的弦中一条与它相交,一条与它不交,因此答案就是 \(\sum \frac{(l_i+r_i) \times (n-1-l_i-r_i)}{2}\)。
CF1168D
考虑暴力怎么做,不难发现两个叶子 \(u,v\) 能够互相重排只需要在它们的 \(\rm LCA\) 处延伸下来的两条链能够互相重排即可。
因此设 \(st_{x,c}\) 表示点 \(x\) 的子树内满足所有叶子都能互相重排至少需要几个字符 \(c\),转移是简单的,过程中判断一下非法即可。
进一步优化是把一条链缩起来,这样每个点的深度只有 \(\sqrt n\)。
ARC173E
考虑 \(X\) 有可能由哪些 \(A_i\) 异或得到。
一个显然的必要条件是这些 \(A_i\) 的个数必须是偶数。
但是这个条件并不是充分的,设这些异或起来的 \(A_i\) 组成的可重集为 \(|S|\),当 \(|S|=0\) 时显然不合法,并且有些情况下 \(|S|=n\) 时也不合法。
考虑证明如果 \(|S| \in (0,n),|S|=2k\) 则一定合法。
考虑归纳证明:如果此时 \(\frac{|S|}{2}\) 是偶数,那么我们将序列排成:\((S_1,S_2,S_3,\dots,S_{|S|},\dots)\),然后就可以令 \(|S|\) 变成 \(\frac{|S|}{2}\);如果此时 \(\frac{|S|}{2}\) 是奇数,那么我们将序列排成:\((S_1,S_2,S_3,\dots,S_{|S|-1},?,S_{|S|},\dots)\),然后就可以令 \(|S|\) 变成 \(\frac{|S|}{2}+1\)。
现在的问题是判断能否选择全集:如果 \(n=4t\),那可以按照 \(|S|\) 是偶数的情况转化为 \(n=4t-1,|S|=2t\) 的情况,自然是合法的;如果 \(n=4t+2\),第一步会让 \((A_1,A_2,\dots,A_n)\) 变成 \((A_1 \oplus A_2,A_2 \oplus A_3,\dots,A_{n-1} \oplus A_n)\),此时若想异或成全集,至少需要选 \(2t+1\) 个,但如果选了 \(2t+2\) 个,根据鸽巢原理,必然会有某个 \(A_i\) 被消掉,此时不合法,所以一定会选 \(2t+1\) 个,但是 \(2t+1\) 是奇数,所以肯定不合法。
接下来问题形如:在 \(n\) 个数里求偶数个数异或起来的最大值(强制钦定不能选全集或不钦定)。
可以使用线性基解决这个问题。

浙公网安备 33010602011771号