2025.2.13 近期练习
P11052 [IOI 2024] 象形文字序列
做一个题的通用思路,就是考虑问题的若干特例,即找部分分做法,然后做“启发式搜索”找最有思路的。
因为最长公共子序列是 NP-Hard,这里要 \(O(n^2)\) 所以我们不能先求出最长公共子序列再判断。
考虑 \(A\) 是一个排列的部分分,那么考虑重编号为 \(1\sim n\),然后相当于 \(B\) 中找上升子序列。
然后后面可以放到平面上 \((i,B_i)\) 去研究,但是这里还是比较麻烦的。
考虑每个元素加起来出现次数 \(\le 3\)。首先只在一边出现的可以直接删掉。那么剩下 \(1+2\)。
如果该元素不出现在最全公共子序列里,但是其肯定可以作为公共子序列出现,所以这肯定不合法。
所以现在每个剩下的每个元素都必须出现。那么出现 \(1\) 次那边必选。现在就变成一个匹配问题,扫一遍即可。
考虑字符集为 \(2\) 的部分分。那么现在相当于有若干 \(0,1\) 是必选的。现在还是匹配。放到平面上表示。
平面上 \((i,j)\) 表示 \(a_i=b_j\) 可以匹配。那么相当于向右向上走,必须经过某的行或某的列(不是穿过)。
那么相当于每时每刻都在一条线上。那么你走到下一个点是不能穿过必经的行的,这个可以求出到底往哪走。
可以求出是否可以向上走或者向右走。然后你发现如果走到第 \(i\) 行的时候能走到的列是一个区间。
考虑更普遍的情况。也是可以用平面刻画的。
你每一步有两种走法,要么在序列 \(A\) 上推到下一个关键位置,要么在序列 \(B\) 上推到下一个关键位置。
然后区间的性质还是存在的。算了后面不会。
Loj #6440. 万能欧几里得
有一条直线 \(f(x)=\frac{px+r}{q}\),然后你要对 \(\forall x\le L\) 的 \(g(x, \lfloor f(x) \rfloor )\) 求和。\(g(x,y)\) 是某种二元函数。
考虑先把直线画出来,再刻画一条折线。从左往右扫,如果直线交到一条横线就向上,交到一条竖线就向右。
如果直线碰到整点那么先向上再向右。那么每次向右走的点都是要求的点。称向右操作为 \(R\),向上为 \(U\)。
也就是第 \(x\) 次向右前一定有 \(\lfloor f(x)\rfloor\) 次向左,对应一个 \((x,\lfloor f(x)\rfloor)\)。每次操作会给 \(g\) 函数带来一些影响。
那么回到正题,我们想要递归地求 \(s(p,q,r,L,R,U)\),不妨分讨 \(p,q\) 的关系即分讨斜率跟 \(1\) 的关系。
若 \(p\ge q\) 那么斜率大于等于 \(1\)。考虑令 \(p'=p- kq\),\(R=U^kR\) 。也就是挖掉了一个斜边斜率为 \(k\) 三角形。
若 \(p<q\),我们希望交换 \(p,q\) 使其回到上一步。根据第 \(x\) 个 R 前有 \(\lfloor f(x)\rfloor\) 个 U,交换 R,U。
那么第 \(i\) 个 U 之前有 \(\lfloor \frac{qx-R-1}{p}\rfloor\) 个 R,然后前后要单独处理,直接记结论。
\(s(p,q,r,L,R,U)=U^{\lfloor \frac{q-R-1}{p}\rfloor}R\times s(q,p,(q-r-1)\bmod p,m-1,U,R)\times R^{L-\lfloor\frac{qm-r-1}{p}\rfloor}\)。
其中 \(m=\lfloor f(L)\rfloor\)。如果 \(m=0\) 就结束。此时贡献是 \(R^L\)。
到任意一道题里面,只要替换 \(U,R\) 即可。比方说这个题可以维护向量 \(\{A^x,B^y,res\}\)。
\(\{A^{x_1},B^{y_1},res_1\}\times \{A^{x_2},B^{y_2},res_2\}=\{A^{x_1+x_2},B^{y_1+y_2},res_1+A^{x_1}\times res_2\times B^{x_1}\}\)。
那么 \(R\) 就是 \(\{A,I,A\}\),\(L\) 是 \(\{B,I,0\}\)。每走一步 \(R\) 就累加的意思。
比方说 P5170 就维护 \(\{cnt_U,cnt_R,\sum x,\sum f(x),\sum f(x)^2,\sum f(x)x\}\) 即可。
CF1634F Fibonacci Additions
考虑如何刻画。算了,直接把这个题记下来就行了。维护”差分“数组 \(c_i=a_i-a_{i-1}-a_{i-2}\),是单点修。
UOJ #692. 【UR #23】民意调查
考虑枚举给子集分组,要么按中位数分组,要么按平均数。显然是按照中位数是比较合适的。
于是枚举中位数是哪个,以及集合的大小。然后剩下就是一段前缀和一段后缀背包拼起来。
考虑降低空间复杂度,考虑从前往后枚举做退背包即可,就可以省一维。复杂度 \(O(n^3V)\)。
P3642 [APIO2016] 烟火表演
我们要研究所有合法方案中边权和最小的。一组合法方案相当于边权的集合。
一个显然以子树为子任务设状态 \(f_{u,i}\) 表示 \(u\) 子树内所有叶子到 \(u\) 长度为 \(i\) 此时所有方案最值。
我们想减少状态维度。维度是相当于给状态分类。
设 \(F_{u,i}\) 表示所有满足上述条件的方案。\(f_{u,i}=\min w(F_{u,i})\)。那我们关心的是 \(w(F_{u,i})\) 集合。
你把 \(i\) 放进方案里。那么 \(F_u\) 就是 \((i,w)\) 的集合。那么直接对方案集合进行递推。
放到平面里去刻画。\(F_u\) 是点集。先考虑一个集合往上长一条边集合的变化。那么 \(F_u\gets F_u+D(x)\)。
其中 \(D(x)=\{(x+k,|k|)\}\)。这里加是两两相加。如果是凸包那么是闵可夫斯基和。
然后考虑合并两个子树,此时必须要横坐标相同的时候纵坐标相加。
然后既然 \(D(x)\) 是凸的,合并两个凸的还是凸的,所以 \(F_u\) 是凸的。那么维护下凸包就行了。
考虑如何表示一个凸包。维护拐点,考虑让每经过一个拐点斜率就 \(+1\) 就好了。\(x=0\) 时答案为边权和。
对位加直接合并拐点。合并 \(D(x)\) 的话就是插入一段 \(-1\),一段 \(+1\)。
那你为什么要刻画方案集合的结构?如果方案能写成二维那么就可以用平面直观表示。比方说你可以打表。
P11051 [IOI 2024] 树上代价
如果跟上一题一样的研究合法方案集合然后变成维护凸包,我看不懂因为题解太史。
考虑 \(w_i=1\) 的部分,那么有一个贪心,就是叶子节点肯定填 \(L\),然后每个点 \(u\) 将其减到 \(R\) 以下即可。
考虑 \(w_i\le 1\) 的部分分,在 \(w_i=0\) 时一定可以调整为任意值,贪心来看 \(L\) 是最优的,那么其就是叶子。
那么设大小为 \(k\) 的连通块有 \(c_k\) 个,代价为 \(\sum_k c_k\max(0,kL-R)\),维护 \(\sum kc_k\) 后缀和即可 \(O(1)\) 查询。
考虑普遍情况,我们盲猜可以向 \(w_i\le 1\) 规约,也就是 01 原理。那么对每个 01 分界点 \(x\) 都算答案并累加。
考虑从大到小加入点也就是相当于维护连通块。可以处理出每个连通块存在的时间,处理出对应贡献。
P4458 [BJOI2018] 链上二次求和
考虑单点加产生的影响,考虑拆贡献算 \(x\) 在长度为 \(i\) 的路径里出现多少次,那么设 \(s=\min(x,n-x+1)\)。
那么对于长度 \(1\sim n\) 的贡献增多了 \(1,2,\dots s-1,s,s,\dots,s,\dots,1\)。这个东西是加等差数列形式。
考虑区间加。考虑拆成两段 \(s\) 的区间。也就是对于 \(s\in [l,r]\) 都进行上面的加等差数列。
那么这就变成了差分数组上加等差数列,拿线段树可以维护。考虑差分数组加的等差数列会发生什么。
也就是算形如 \(\sum (c-i)i\) 这种,那么只需要知道 \(\sum i^2,\sum i\) 是不是就行了。或者可以看成区间加二次函数。
但是这玩意有点麻烦,考虑简单点的办法。你可以暴力拆成 \(k\) 阶前缀和相加减的形式。
例如这个题就可以拆成 \((r-l+1)\sigma^3g(n)-\sigma^4 g(r-1)+\sigma^4 (l-2)-\sigma^4(n-l)+\sigma^4(n-r-1)\)。
其中 \(g\) 是差分数组。那么现在就是如何维护 \(k\) 阶前缀和,考虑 \(g(j)\) 对 \(\sigma ^kg(i)\) 的贡献是组合数 \(C_{i-j}^k\)。
而组合数其实是一个关于 \((i-j)\) 的 \(k\) 次多项式,再把 \(i,j\) 独立,展开 \((i-j)^k\) 就行了,把系数放在 \(i\) 处算。
那么现在用树状数组维护 \(g_jj^k\) 的前缀和即可。
P8350 [SDOI/SXOI2022] 进制转换
考虑根号分治。考虑将一个三进制数拆成 \(i=p+3^Bq\),此时 \(x^i=x^p\times x^{3^Bq},z^{b(i)}=z^{b(p)}\times z^{b(q)}\)。
如果 \(y=1\),合并 \(p,q\) 此时就很好算,两部分加和乘起来就好了。因为我们把三进制数拆开了可以直接积。
考虑 \(y\neq 1\),我们要算二进制位个数的贡献。有一个小的二进制数 \(p\) 和大的二进制数 \(3^Bq\)。
那么我们列加法,设 \(p\) 二进制位数为 \(c\),只需要 \(c\) 以下有无进位给 \(3^Bq\),相当于只用做 \(c\) 位以下的合并了。
这里是个卷积。分讨 \(3^Bq\) 是否被进位,对应不同的贡献,然后考虑做 NTT 即可。
如果进位就取 \(\ge 2^c\) 的,反之亦然。相当于把二进制数也拆开了,可以直接积。
这种思想相关 meet in middle,使得贡献可以独立计算,再利用分配率的逆过程。(因式分解)
P11364 [NOIP2024] 树上查询
你考虑将 \(lca(l\sim r)\) 看成一个二元函数,然后现在就变成了研究函数的结构,考虑放到平面上去研究。
有一个通用的研究方法就是研究 \(lca=u\) 时的形状。然后相当于变成研究合法集合。变成一个组合模型。
那么如果 \(f(l_1, r_1)=f(l_2,r_2)=u\),考虑这两个区间的关系,关系有三种。
如果是包含,那么大区间所有子区间都为 \(u\);如果是相交,那么两区间之并也是 \(u\)。
放到平面上,那么 \(f(x,y)=u\) 的 \((x,y)\) 的形状形成一个阶梯型。
其中,阶梯的每个相邻的凸点并起来形成了凹点,阶梯左上方代表最大的区间,也是另一个阶梯的凹点。
而阶梯之间的关系就形成了一棵有根树。这棵树是一棵区间的合并树。相当于深度的小根笛卡尔树。
现在考虑原问题。把每个阶梯的左上角的点拿出来,一共有 \(O(n)\) 个,相当于给其右下的所有点 chkmax。
然后考虑查询,查询是查询一个斜率为 \(1\) 的最大值,那么考虑能影响到这个线段的所有点。
可以看做是两个矩形和一个三角形的并中,查上述点的 \(\max\)。三角形很难搞,将其补全为一个斜着的矩形。
那么把斜的旋转一下就变成简单扫描线了,复杂度单 \(\log\)。
还有个问题就是阶梯型怎么求。也就是你 dsu on tree 的时候当有新的连续段出现的时候就对应一个新的点。
当然这个题还有很套路的做法就是 \(dep_{lca(l,r)}=\min_{i\in[l,r-1]} dep_{lca(i,i+1)}\)。
考虑求出 \(dep_{i,i+1}\) 为答案的极长区间 \([x,y]\),然后就是与询问区间 \([l,r]\) 求交集 \(\ge k\) 的最值了。
条件分讨 \(y,r\) 的关系,是两个选一个:\(y\ge r, x\le r-k+1\) 或 \(l+k-1\le y\le r,y_i-x_i+1\ge k\)。
这个扫描线扫两次,一次扫 \(x\),一次扫 \(k\) 就行了。
P8528 [Ynoi2003] 铃原露露
考虑打表观察。比方说你钦定几个区间必须合法然后观察一下有没有别的性质。相当于研究合法区间集合。
区间合法的条件是所有点形成虚树(无其他点)。那么两合法区间之交肯定合法。
那考虑有交的区间并可以吗,发现大部分合法。反例是比方说两区间各自存在一对 \((u,v)\) 他们 lca 非常深。
所以区间合法的另一种表达是不存在一个非区间的点其有 \(\ge 2\) 个子树有点。这也是一个想法。
还有一个想法是固定左端点然后观察右端点移动时的变化。
考虑结合一下,考虑若 \(lca(a_x,a_y)=a_z\) 那么 \(z\) 在 \([x,y]\) 之外的话那么若包含 \([x,y]\) 就必须包含 \(z\)。
我们考虑研究不合法时函数的形状。比方说 \(z\) 在 \([x,y]\) 之外但是包含了 \([x,y]\) 没有包含 \(z\) 就是非法的。
比方说钦定 \(z>y\),那么 \([1,x]\times [y,z-1]\) 是非法的。然后就是覆盖一个矩形。最后没有被覆盖的就合法。
但是非法矩形太多了。但如果小矩形被大矩形包含就可以删了。所以假设 \(z>y\),那么只有最大的 \(x\) 有用。
所以相当于 dsu on tree 的时候,插入一个点就考虑其相邻的位置即可。
所以矩形个数是轻儿子子树大小之和。也就是 \(O(n\log n)\) 个矩形,扫描线的话维护历史最小值个数即可。
这个做法是研究非法函数形状。上一题是研究每种函数取值的形状。
维护 upd 代表被累加进历史和次数,修改时当 Mn=0 才更新 updh,下传的话只有 Mn 跟父亲一样才下传。
然后 h = h + ct * updh 即可。
Loj #6913. 树莓立方体
考虑研究函数的结构,因为最后要求哈希,那么只有研究每种函数取值的形状一条路了。
\(\min,\max\) 这些基于比较的考虑 01 原理。先考虑只有 01 怎么做。
若函数里取 1,那么代表 \([l,r]\) 区间在满足 \(\le k-1\) 个序列不都全是 \(1\),这相当于区间交。
考虑放到平面上去处理。对于极长的合法区间 \([l,r]\),相当于 \((l,r)\) 右下角三角形都为 \(1\)。
考虑 01 原理,从大到小加入数 \(x\) ,然后算 \(x\) 这个序列包括 \(x\) 的极长 \(1\) 区间 \([l,r]\)。这个单调栈做就行了。
我们这里不用管别的序列,因为我们总是最大的最先赋值。
这里跟上面有一些不同。我们要将 \((l,r)\) 右下角的矩形中还没有被赋值的赋值为 \(x\)。
因为已经赋值的形状形成阶梯型,考虑维护阶梯左上角的点,均摊 \(O(n)\) 个矩形赋值,后面就扫描线历史和。
这个题狠狠锻炼我的实现我服了。细节主要在于维护阶梯,还有历史和千万别写错。
qoj # 9222. Price Combo
最优化问题考虑方案集合。一组方案就是元素被划到哪边买的决策集合。不妨放到平面上去表示。
最优化问题基本研究方式是调整。考虑若 \(a_i>a_j,b_i<b_j\) 那么肯定是 \(i\) 在 B,\(j\) 在 A 最优。
放在平面上就是 A 不能在 B 的右下角。也就是说存在一个分界线,左上是 A 右下是 B。
这种问题为什么要放到平面上呢?也就是我们关系他们的大小关系,那么模型是二维偏序。
考虑一个方案的贡献,即 A,B 分别排序然后取第 $1,3,5,7\dots $ 大的加和。A,B 分别排序就很难处理。
然后考虑 dp 这个折线,贡献如何计算?考虑折线向右走对应上面一列的选 a,向上走对应右边一行选 b。
这样巧妙地使得加入 A,B 都是分别排序了的。而不是一行一行加入就始终有 a,b 一个没排序。
具体实现对 \(a_i\) 扫描线,维护当前 \(dp_{j}\) 表示 \(b_i\ge k\) 的选 B,反之选 A 此时的答案。
然后你一个位置有四种状态,对应当前 \(a,b\) 的奇偶性,然后就做完了。线段树维护”整体 dp“即可。
P5371 [SNOI2019] 纸牌
合法性判定底层是一个构造问题。构造问题考虑调整。
从最小的开始,如果先把 \(3\) 个一组的全部拿出来,那么后面有几个顺子就已知,归纳证明是唯一构造。
那现在就是一个线性递推,并且状态数是 \(O(1)\) 的。你这个不是唐题吗。算了写都写了。
这种叫自动机判定。
P5279 [ZJOI2019] 麻将
如果你按照 \(P\) 顺序加入去计算的话有若干问题,就是一是很难判定,二是状态压不下来。
期望的线性性 \(E=\sum p(S,x)\times (|S|-13)\),其中 \(p(S)=\) 加入 \(x\) 后刚好合法的概率 * 达到 \(S-x\) 的概率。
或者可以看做每个非法 \(S\) 都对其后面的有了 \(1\) 的贡献。然后就相当于 \(E=\sum p(S)\)。
\(p(S)\) 是 \(S\) 非法且达到的概率,其实就是 \((C_{4n-13}^{|S|})^{-1}\)。
那么按照牌面从小到大加入 dp 就可行了,现在考虑设计判定自动机,这东西跟上面还是比较像的。
判定自动机可以用 dp 的形式来实现,那么就是一个 dp 套 dp 罢了。
CF1605F PalindORme
考虑自动机判定,考虑每次选两个相同的数 \(x\),将其放在序列两端,再将剩下数的二进制位跟 \(x\) 重合的删了。
重复上述过程直到只剩下 \(\le 1\) 个数,那么就合法。考虑把自动机判定换成一个静态的条件。
那么若序列存在一种划分 A,B,B 扣掉 A 的二进制位后互不相同,且 A 满足能放在序列两端,那么便非法。
但这个条件很麻烦,其实 A 的条件是可以扣掉的,只需要保证 B 扣掉 A 二进制位互不相同即可。
如果把一个非法解按照 A 分类,我们就有了一个初步的 dp 框架。
设 \(f_{i,j}\) 表示长度为 \(i\),二进制位覆盖 \(j\) 个的序列数,\(g_{i,j}\) 表非法序列数,\(h_{i,j}\) 表没有 \(0\) 且两两不同的序列数。
\(f_{i,j}=\sum_{k\le j}(-1)^{j-k}C_{j}^k (2^k)^i\)。
\(g_{i,j}=\sum_{i'<i} \sum_{j'<j} C_{i}^{i'}C_{j}^{j'}(2^{j'})^{i-i'}h_{i-i',j-j'}(f_{i',j'}-g_{i',j'})\)。
\(h_{i,j}=\sum_{k\le j} (-1)^{j-k}C_j^kA_{2^k-1}^j\)。
为啥 \(h_{i,j}\) 表示的不能有 \(0\) 呢,因为我们一个非法序列需要有一种唯一 A 表示的方法,如果有 0 就有两种了。
还有一个问题就是若 \(n\) 为奇数的非法序列不能从长度为 \(n-1\) 的合法序列转移过来。
学习到了。我们摒弃对多重集 dp,而是直接对序列 dp,也这样就避免了元素贡献计算以及插入顺序的问题。
而变成序列的话,子集的划分相当于子序列,也就是条件啥的不会变。
即对于一个非法解,其势必存在一个合法的子序列。删掉这个子序列划分子任务就好了。
AGC058D Yet Another ABC String
你考虑刻画性质。考虑差分,那么一个串合法的条件是(除去第一位)的差分数组没有连续两个 \(1\)。
那么考虑容斥。现在有一个问题,就是合法是没有 \(1\) 的超过 \(\ge 2\) 的连续段还是没有 \(1\) 的长度为 \(2\) 的连续段。
这关系到钦定的问题,显然是前者好算,因为后者还需要处理有没有叠起来的问题。我的理解。
也就是钦定有 \(i\) 个 ABC...,BCA... 或 CAB... 算答案。并且这些必须是非法的连续段的开头。
考虑算贡献。如果起点在首位那么贡献为 \(3\),否则为 \(2\)。然后剩下贡献就是选起点位置以及剩下任意排列。
P6846 [CEOI 2019] Amusement Park
考虑一个方案反转了 \(x\) 次,那么反转 \(m-x\) 次一定可以变为其反图。所以我们只需要求方案数 \(\times \frac{m}{2}\) 即可。
考虑设 \(f_S\) 表示 \(S\) 子集里定向为 DAG 的方案数。考虑子任务,那么也就是拿出拓扑序在最外面的点。
而最外面的点是一个独立集,设为 \(T\),那么 \(f_S\) 的子任务是 \(f_{S-T}\)。
考虑会算重。每种方案都被一种 \(T\) 算了一次。那么容斥就行了。也就是 \(f_S=(-1)^{|T|-1}f_{S-T}\)。
复杂度 \(O(2^nm+3^n)\)。
CF756E Byteland coins
考虑从小到大使用金币,设第 \(i\) 种面额为 \(d_i\),那么用完前 \(i\) 种的时候当前值必定是与 \(m\) 同余 \(d_i\)。
设 \(g_{i,j}\) 表示当前面额为 \(j\times d_i+m\bmod d_i\) 此时的方案数,设 \(sz_i\) 表示最大的有值的 \(g_{i,j}\) 的 \(j\)。
考虑计算 \(sz_i\) 的大小,那么 \(sz_i\le \sum_{j}b_j\frac{d_j}{d_i}\),那么也就是前面的影响会被稀释,而每次都至少减少 \(1/2\)。
而 \(1/2+1/4+\dots=1\),所以 \(\sum sz_i=O(\sum b_i)\),但是因为面值有重复所以是 \(O(k\sum b_i)\)。
考虑用前缀和优化背包即可。现在只是面临一个高精的问题,稍微处理即可。复杂度是 \(O(\sum sz_i)\)。
CF2066D2 Club of Young Aircraft Builders (hard version)
考虑研究对象如何表示。考虑用每个位置被放满的时间序列 \(t_i\) 表示。那么可以把每种合法序列分类。
显然 \(t_i\) 是递增的,且 \(t_i\) 是形如一段一段的,考虑放到平面上去研究。把所有 \((i,p_i)\) 拿出来。
假设我们要让 \([x,y]\) 这一段的 \(t\) 都是 \(i\),若上一段的 \(t\) 为 \(j\),研究一下条件。
那么 \([j+1,i]\times [1,y-1]\) 这个矩阵里不能有点,即横坐标在 \([j+1,i]\) 里的点必须不低于 \(y\)。
进一步地,时间轴上每段的长度 \(\le c\),那么 \(x\) 能放的位置不超过 \([1,x-1]\) 出现的个数 \(+c\),且个数 \(\le c\)。
事实上,上述转化的条件是充要的,相当于将依时间轴前进变化为依下标前进观察条件。
那么现在设计 dp。考虑设 \(dp_{i,j}\) 表示已经放置了 \([1,i]\) 里所有数,总共放了 \(j\) 个数的方案数。
转移考虑枚举 \(i+1\) 填的个数,用组合数转移即可。还有一个条件就是 \(n\) 必须放满。
有一个严重的误区!就是别用“断点转移”,就是别把连续段当成阶段,这样很不好做。
CF2066E Tropical Season
只有判定出来相等是有用的,那么这两个桶都是没毒的。反之若他们理应相等却不等就找到了。
考虑你当前有两个一样的桶 \(k\),那么你可以得到自由支配的水 \(L=2k\),然后去找另一对相等的。
重复上述过程,如果最后排除了 \(n-1\) 个没毒的桶就合法。
考虑有两种操作,一种是如果有 \(a_i\le L\),那么可以使得 \(a_i\) 排除,再令 \(L\gets L+a_i\)。
一种是如果 \(a_j+L\ge a_i\),那么将 \(a_j\) 倒入 \(a_i-a_j\) 的水量之后再判定,\(a_i,a_j\) 被排除,\(L\gets L+a_i+a_j\)。
考虑倍增值域分块 \([2^k,2^{k+1}-1]\),容易发现一旦块内一个元素被排除,那么整个块都可以被排除。
设一个块内的可重集是 \(S\),那么需要有 \(L\ge \min_{a_i\in S,j\neq i,a_i\le a_j} (a_j-a_i)\),或者 \(L\ge \min _{a_i\in S} a_i\)。
考虑块间的贡献,我们只用考虑相邻块。如果一个块内没有值导致后继值在下下个块,那势必 \(> 2^k\) 不优。
一个块内维护一个 multiset,于是做完了。
uoj #806. 【UR #25】见贤思齐
还是考虑如何描述整个过程。先考虑树怎么做。
设 \(f_{i,t}\) 表示 \(i\) 这个点在 \(t\) 时刻的取值。那么 \(f_{i,t}=f_{i,t-1}+[f_{i,t-1}\le f_{p_i,t-1}]\)。
那么上述式子存在一个问题就是若想知道 \(f_{i,t}\) 的值还需要知道 \(f_{i,t-1},f_{p_i,t-1}\dots\) 相当于需要知道所有 \(f_{i,t}\)。
考虑 \(i\) 的取值范围显然为 \([a_i,a_i+t]\)。只需要考虑 \(f_{p_i,t-1}+1\) 的取值判断一下是否属于这个范围即可。
那么 \(f_{i,t}=\max(\min(f_{p_i,t-1}+1,a_i+t),a_i)\)。考虑消去 \(+1\) 常数。
那么设 \(g_{i,t}=f_{i,t}-t\),则 \(g_{i,t}=\max(\min(g_{p_i,t-1},a_i),a_i-t)\)。
那么这个过程可以看做是 \(g_{i,t}\) 的取值范围不断缩小的一个过程,起初是 \([a_i-t,a_i]\),再跟 \(g_{p_i,t-1}\) 取交。
直到交为空集,也就是存在一个 \(g_{j,t'}\) 取值范围和 \(g_{p_j,t'-1}\) 不交了,肯定取到 \(a_j,a_j-t\) 中的一个。简单判定。
我们可以用倍增实现这个过程。也就是维护 \(a_i-dep_i\) 最大值和 \(a_i\) 的区间最小值即可。
考虑基环树怎么做。考虑把环上最小的那个点拿出来,这个点肯定一直 \(+1\),于是将其这个点设为根即可。
其实实现来看上面这步好像没必要。
P7214 [JOISC 2020] 治療計画
考虑刻画问题。如果没有时间维那么就是线段覆盖问题。
考虑在平面上刻画。拿出下标-时间二维平面。我们考虑一个方案就是一个斜边平行 \(x\) 轴的一个等腰三角形。
那么,要想要覆盖 \(1\sim n\),相当于沿着三角形的边走,存在一条从 \(x=1\) 到 \(x=n\) 的折线。
那么可以转化为一个最短路问题,考虑建图。
钦定 \(T_j<T_i\) 并分离 \(i,j\),那么需要满足 \(L_j+T_j-1\le R_i+T_i\),或者 \(R_j+T_j+1\ge L_i+T_i\)。
这个东西是一个二维偏序,按照 \(T\) 加入,考虑用主席树优化建图即可。
观看题解得到:权在点上的最短路有一个性质:每个点最多被松弛一次。所以每个点出队的权值就是其真权。
所以我们可以不用把图建出来,也不需要用主席树,直接在线段树上维护最短路的权值即可。
考虑势能线段树。考虑现在取出队顶的点来松弛,分讨其作为 \(T\) 是大的还是小的,也就是时间轴上前后缀。
形如将区间内 \(R_i+T_i\le x\) 的点松弛,按照势能线段树一般形式维护区间 \(\min\),然后递归整棵子树。
如果一个点已经被松弛那么就将其设为 inf。复杂度应该是 \(O(n\log n)\)。
注意这里线段树上的点是不用入队的。线段树只是起到了一个维护势能的作用。
AT_cf16_exhibition_final_e Water Distribution
考虑调整。如果 \(a_i\to a_j,a_i\to a_k,a_j\to a_k\),这样不如 \(a_i\to a_k,a_j\to a_i\)。
所以我们可以猜想最后有流的边是森林。
考虑如何计算答案。考虑将 \(\max(0,l-d)\) 改写为 \(l-d\),因为最优方案肯定不含 \(<0\) 的边,不会影响答案。
考虑一棵树的答案,考虑答案上限,也就是 \(\frac{\sum a_i-\sum d}{|T|}\),这个是可以被取到的。
后面考虑状压 dp,先预处理每个连通块的答案,然后再做子集 dp 就行了。
我想知道这种转化的内涵,如同拆绝对值那样,或者叫增强限制,只是为了好算吗?
CF1874F Jellyfish and OEIS
研究 \(p_{l\sim r}\) 不是 \([l,r]\) 的排列这个函数的性质。若 \([l,r]\) 满足,\([r+1,r+1]\) 满足,那么 \([l,r+1]\) 也满足。
似乎真的没什么性质草了。考虑若 \([l,m_l]\) 到 \([l,r]\) 都不是排列会带来什么。我们可以先保留思路。
但是如果条件改成是一个排列,就有区间并和区间交的性质了。并且区间反交也是合法的。
当没有头绪的时候考虑容斥。也就是钦定若干区间为排列。此时我们可以用上区间反交也是合法这个条件。
那么可以带来什么呢?假如我们钦定了两个相交的区间都非法,等价于三个小区间都非法,这两部分抵消。
上面说的相交不含包含关系。所以我们容斥只需要钦定的若干包含或分离区间非法就行了。
那么这就是一棵区间树。假设知道一棵区间树的贡献就是”每个区间扣掉子树区间大小“的阶乘之积。
考虑如何计算答案。考虑区间 dp,设计状态为 \(g_{l,r,x}\) 表示 \([l,r]\) 有 \(x\) 个空点,子树贡献都算完的答案。
转移的话枚举子区间是哪些,同时记 \(f_{l,r}\) 表示 \([l,r]\) 被钦定非法时的答案。答案其实是容斥系数*方案数之和。
\(f_{l,r}=-\sum g_{l,r,x}\times x!\),\(g_{l,r,x}=g_{l+1,r,x-1}+\sum f_{l,r'}\times g_{r'+1,r,x}\)。如果 \([l,r]\) 不能被钦定就是 \(0\)。
P7670 [JOI2018] Snake Escaping
这个题很典,考虑鸽巢原理,对于一次询问肯定有 0,1,? 中的一种个数 \(\le n/3\)。
如果 ? 的个数 \(\le n/3\) 我们可以直接枚举。
对于这种问题可以考虑高维前缀和,那么我们已知一个集合里元素之和,相当于已知只含 0? 的串的答案。
对于 1 的个数 \(\le n/3\) 的情况,不妨将 1 看做 ?-0,然后将其展开求和即可。
对于 0 的情况也同理,求一个高维后缀和即可。那么整个问题复杂度为 \(O(q2^{n/3})\)。
CF1322D Reality Show
考虑已知能力值为 \(i\) 有 \(c_i\) 个人会发生什么。首先 \(2\) 个 \(c_i\) 会贡献给 \(c_{i+1}\),然后 \(2\) 个 \(c_{i+1}\) 又会贡献下去。
考虑算一下贡献,\(i\) 处的贡献是 \(c_{i}\gets c_{i}+c_{i-1}/2\)。但是 \(c_{i-1}\) 又是未知的,递归算即可。答案是 \(\sum s_i c_i\)。
感觉跟二进制有点像。如果我们从大到小加入数这样会有后效性,不妨从小到大加入数。
那么现在状态就可以用一个二进制数表示,代表处理了 \(\le x\) 的数此时进位的情况。
而这个进位显然是 \(\le O(n)\) 的,所以我们有了一个状态数为 \(O(n^2)\) 的表示。看上去没有什么优化了怎么办。
考虑加入一个数 \(x\)。假设我们要用 \(f_{y,s}\) 的状态来更新,那么 \(s\) 二进制下的后 \(x-y\) 位是没用的。
那么有用的状态是 \(n+n/2+n/4+\dots =O(n)\) 种,理论可行 \(O(n^2)\),考虑如何维护这个过程。
不妨只维护是 \(F_{y}=\max f_{y,s}\),当 \(y\) 影响不到 \(x\) 的时候调用 \(F_y\),其他的枚举所有状态。 \(O(n^2\log n)\)。
CF1844G Tree Weights
一开始我以为 \(dis_{i,i+1}\) 就可以组合出所有 \(d_{x,y}\)。知道 \(dis_{x,y}\) 就只要知道 \(dis_{x,x+1}\) 与 \(dis_{x+1,y}\) 是怎么组合的。
但是这是错的,\((x,y)\) 路径与 \((y,y+1)\) 路径可能有重复,但这个重复的路径还要算呢。
考虑定根。那么 \(dis_{i,i+1}=d_{i}+d_{i+1}-2d_{lca(i,i+1)}\),那么这个东西是一个线性方程组。
考虑递推计算,已知 \(d_1=0\),那么 \(d_{i+1}=dis_{i,i+1}-d_i+2d_{lca(i,i+1)}\),问题就是要调用没有算的值。
考虑拆位考虑 \(\bmod 2\) 的值。那么 \(2d_{lca(i,i+1)}\) 就没了。此时可以直接求出来。
考虑计算下一位 \(\bmod 4\) 的值,此时调用上一位求的 \(d_{lca(i,i+1)}\) 值即可。真的是奇妙啊。
这种拆位的思想可以考虑 qoj # 9479. And DNA。最后稍微判一下是否是正整数即可。
CF1616H Keep XOR Low
这个题其实不难。位运算问题考虑用 trie 树处理。然后拆位从高位到低位处理。
考虑若 \(x\) 这位为 \(0\) 那么就是左子树和右子树不能同时选。
若 \(x\) 这位为 \(1\) 就比较麻烦。如果只有左子树或者右子树那么就是随便选。考虑左右子树同时有点。
左右子树同时有点的话相当于他们之间匹配还顶着最高位限制。不妨称这是个子任务 \(s(A,B,k)\)。
考虑解决 \(s(A,B,k)\) 表示 \(A,B\) 两个集合异或 \(\le\) \(x\) 的后 \(k\) 位的答案,还是分讨 \(x\) 该位取值。
若为 \(0\),也就是不能处于不同集合的一个左子树和一个右子树被选,跟上面很像吧。
也就是子任务 \(s(ls_A,ls_B,k-1)\) 与 \(s(rs_A,rs_B,k-1)\) 的答案加起来。
考虑 \(1\) 的情况。考虑如果两个集合都只有左子树或右子树那么可以任选;
先考虑其中一个集合左右子树都有。不难发现两个集合都有的那边的子树是没用的,可以任选。
两个集合左右子树都有呢?我们发现两个问题独立。\(s(ls_A,rs_B,k-1)\times s(rs_A,ls_B,k-1)\)。
考虑复杂度问题。这里的集合考虑用 trie 树上的点表示。
每层只有 \(O(n)\) 个子任务,那么复杂度是 \(O(n\log n)\)。
P11666 [JOI 2025 Final] 邮局 / Post Office
考虑一个问题我们要决策的位置,也就是当有多个包裹在一个点的时候哪个先发。
因为基环树上路径是唯一的,所以同一个点两个包裹的路径也就是谁远谁近的问题。调整可得先发远的更优。
通过调整可知,如果一个包裹要等,那么其在哪个点等是没有区别的,看做是在出发点等。
那么这说明什么呢,如果我们只求一个点是如何决策的,这个点和其他点计算是独立的,包括其之前的点。
而答案就是所有点最后一个离开的时间。那么这就简单了,设 \(d_{1\sim k}\) 表示所有到 \(u\) 路径花费的时间。
依据我们上面的贪心,那么 \(u\) 这个点的答案就是 \(\max d_i+i\)。其中 \(d\) 为降序排序。
考虑维护 \(d\) 集合。如果没有环的话考虑线段树合并处理。先递归右子树然后给左子树加上右边的 cnt 即可。
考虑环怎么做。其实直接把环拆了然后复制一遍就好了。然后跨越你断的位置的路径拆成两段即可。

浙公网安备 33010602011771号