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 即可。
考虑环怎么做。其实直接把环拆了然后复制一遍就好了。然后跨越你断的位置的路径拆成两段即可。

posted @ 2025-02-13 21:11  s1monG  阅读(107)  评论(0)    收藏  举报