Exemplary Examples VI
导语见 Exemplary Examples I。
T-118-2 续
对于本题来说,不妨让某线段树的根作为答案。对于第一个问题,很自然地定义线段树信息为“本节点区间内满足 \(i<j\) 的 \(a_i+b_j\) 最大值”,容易合并,也容易做单点删改。对第二个问题,定义为“本节点区间内满足不跨过‘零流量反边’且 \(i>j\) 的 \(a_i+b_j\) 最大值”,容易合并,也容易做单点删改,但当流量做区间修改时,如何处理呢?需关注的元素是“零流量反边”,必须 \(O(1)\) 得到本区间的改后信息。要么是加,将区间内的边都改成正数,\(O(1)\) 得改后信息是容易的。要么将某些正数改成零,得改后信息需要从子树一路合并上来,显然不易,这不该是查询的时候做的事情,应该是早就算好放在那里等候调用。那我要什么,我要计算“若对本节点区间做若干次操作,把一些正数改成零,信息是什么”,这是容易合并的,因为它相当于“若将本节点区间的所有最小值改成零,信息是什么”。
法二,转最小费用任意流,用 wqs 二分去除 \(k\) 的限制。转为增量模型,选择增量轴为时间轴,逐步添点边。假设当前添入了 \(s\to i,i-1\to i,i\to t\) 这三条边,可能的负增广路、负环就形如:
s->i->t
t->j->i->t
s->j->i->t
s->i->t->j->k->s
那么,你可能会问,为什么没有 t->j->i->s 这种东西(称作“反路”)呢?回答是,\(i\to s\) 剩余流量为零。再问,为什么不能在用一些负环、负增广路调整后,使得 \(i\to s\) 剩余流量不为零时,再采取“反路”呢?好吧,如果考虑“反路”,在最优方案中,找出所有涉及 \(i\) 的负环和负增广路,问它们的“合效果”是什么(正反边流量抵消,结果是什么)。必然是一些与 \(i\) 无关的负环和负最短路,以及一些涉及 \(i\) 的负环和负最短路。而一端点为 \(i\) 的那些边,在各个“涉及路”中,其流向必然相同。换句话说,“反路”无用,增量-最小费用任意流模型所关注的新路,它涉及到的新边,其流向必须和添加新边时的相同。
搞定了。翻译成反悔贪心策略,就是:
新选 \(a_i,b_i\) 构成配对。
用 \(b_i\) 替代旧 \(b_j\),拆散 \(j\) 所在配对,改为与 \(i\) 组对。
新选 \(a_j,b_i\) 构成配对。
用配对 \(a_i,b_i\) 替代旧配对 \(a_j,b_k\)。实际并不优秀,因为可以分成两步走,不用考虑它。
好,现在本题已经通过了。我们来看 wqs 二分的优越性在哪里。如果你当初选择全加 -inf 直接转,流量限制 \(k\) 保持,那么上述增广路对源流量的影响是:加一;不变;加一;不变。对最后一个负环不优的证明是,它能分成两步走。但是若源流满,就分不成两步了。故必须实际考虑最后一个负环,而考虑它并不比法一简单。
T-118-2-eg1 CF2147F
这个可不是网络流啊。
跟 T-115 类似,是竞赛图,两张成链的竞赛图叠一起。问可达性,所以需要缩点。不妨先将元素依第一个序列排序,那么一个强连通分量内的元素一定是排序后的一个连续段。令 \(a_{p_i}=s_i\)。考察每一条第二链边 \(i\to a_i\) 的作用,它将 \([i,a_i]\) 确定为在同一连通分量里。从而,未被 \([i,a_i]\) 覆盖的部分就是分量的缝隙。知道缝隙在哪里,就好办了。这是单答案问题,上值域线段树直接合并信息来处理即可,重要的只有零的位置。当然,原问题有修改。这个修改呢,可能会把零改没了,也可能把零改出来。那不就跟 T-118-2 完全一样吗?
T-119 ARC156F 26-3-16 B
二选一问题,常常建图。第一个方法是,考虑网络流,采用集合划分模型;或者还是网络流,给一次决策建立虚点,向两个可能的选项连边。第二个方法是,当作类 2-sat 问题处理。第三个是,在选项之间连边,转化为给边定向的问题,这个方法要可行的前提往往是,建出来的图是特殊图,可以通过度数-节点数-边数这些势能量辅助分析,如树/基环树什么的。本题选择网络流的第二种。
T-120 CF1517G 26-3-16 B
有代价删元素,使得不出现某子图。最小割有三个模型,一个是“路径不通”,每一条从源到汇的路径上,必须有一个边割掉。一个是“集合划分模型”,还有一个是“切糕模型”。第一种模型,直接解决了 T-113-2;第一种模型还能方便地处理“一个集合内,至少删除一个元素”的问题。如本题所述,建图目标就是把这些元素串成一条从源到汇的路径,同时拆点表示代价。但路径的顺序不能乱,如果乱了,可能会存在意想不到的路径,这意料之外的路径也是从源到汇,所以必须割,但原题可能没有这一条限制。为了避免这种情况存在,往往需要分层,要求同层任两个元素,不同时处于任一个路径内。本题中按照横纵坐标奇偶性分四组,用于分层即可(按奇偶性/剩余系分组是套路,在网络流题目中尤其常见)。
T-122 ARC150F 26-3-16 A
最优化问题,贪心/调整不太了,似乎很难直接数据结构做,不妨 dp。如果非要 dp,那状态一定是“\(f_s\) 表示所有和为 \(s\) 的子序列都出现了,最小答案是多少”。写下转移,发现是半在线形式,考虑 cdq。
注意 dp 数组单调(我想,是不是,对于你得到的所有数组,都得优先考虑其是否具备单调性;如果不具备,且没思路的情况下,尝试检查其凸性)。据这个单调性,可枚举洛谷题解中提到的 \(\mathrm{next}_{i,x}\) 等于多少(因为转移是取 max,且有单调性,所以只要 \(\mathrm{next}_{i,x}<f_{\mathrm{mid}}\) 就不好。但是注意到 \(\mathrm{next}_{i,x}>f_{\mathrm{mid}}\) 时,\(\mathrm{next}_{i,x}\) 就是 \(f_{\mathrm{mid}}\) 之后的第一个 \(x\),因此只有满足 \(x\le r-\mathrm{mid}\) 的 \(x\) 会是合法的,这样一来只有 \(O(r-\mathrm{mid})\) 个合法的 \(\mathrm{next}_{i,x}\) 会有用,枚举它们也是非常容易的),以这个玩意为主体,考察所有用到它的转移,转移来源是一个区间(由单调性),去向也是一个区间,直接处理即可。
T-124 P4425 26-3-16 B+
用一手调整法,显然不会等,因为可以向右压缩。例如时刻-物品情况如下:******1122334。可改为 *********1234 肯定没问题。所以不等,那就是从某个时刻开始由某个物品转了几圈,那显然只需转一圈。枚举起始物品,可求得最小开始时刻。经过一番式子转化(改变枚举顺序),变成了 \(\min p_i+a_{p_{i-1}}\) 满足 p 是某序列的后缀最大值序列;对该序列进行单点修改。
是不是单答案问题?试用线段树的根代表答案。那么看到后缀最大值,就可以上单边递归线段树了。
T-125 一些小构造 26-3-16 B+
T-125-1
黑板上有 \(n\) 个整数从一到 \(n\),可以选择任两个加上一个正整数,希望它们最终都相同,问能否合法,并构造方案。
取数和奇偶性为势能量,则该势能量操作过程中不变。假设 \(n\) 是偶数,那么 \(\binom{n}{2}\)(初始势能量)必须是偶数,因此若 \(n=4k+2\) 必无解。下给出其余情形的构造方案。不妨设某 \(q\) 为最终大家都等于的数(取 \(q\) 为最小的 \(q\ge n\) 满足 \(nq\equiv \binom{n}{2}\) 应该就是合适的)。采取归纳构造,倒序处理,每次把涉及原数 \(i\) 的所有操作都一次性搞定。容易证明,把所有操作拆成正整数大小为一的,必不劣。由类似 Havel-Hakimi 的构造方式,我们每次在编号小于 \(i\) 的元素中,选择“剩余需求”最多的那个,与 \(i\) 配对构造一次操作,如果有多个,优先选择编号最大的。那么这样一来,容易证明在归纳构造 \(i\) 时,\(i\) 的“剩余需求”必然比任何 \(j<i\) 的“剩余需求”都要小或等于,故没问题。唯一可能出现的问题是,最后一个元素编号为 \(1\) 的存在“剩余需求”,而显而易见地,它不会是二(这样的话,当初它就会是“剩余需求多”的,当初就会砍它),最多是一。如果是一,这说明奇偶性不对,与假设矛盾。
T-125-2
有 1,2,3,...,1000 各 9 个,共计 9000 个数,需要填入一个 9 行 1000 列的表格,要求对每一列,元素绝对值之差小于等于三。求每列元素和的最小值,的最大值。并给出构造方案。
关注边界元素 1,考察所有包含 1 的列,先求出“尽量让含 1 的列元素和的最小值最大,这个值是多少”。描述它们分别含 1 \(a_i\) 个。这些列必然只包含 1,2,3,4 中的元素,因为共计 36 个,故最多有 4 列。在这些列含 \(a_i\) 个的基础上,令每列“当前元素和”初始化为“列内 1 的个数,加上列内非 1 的个数乘以二”。容易感受到下述贪心方案正确性:依次考虑 4,3,2,例如考虑到 4 时,不断将一个 4 填入“当前元素和最小”的列,并将该列的“当前元素和”加上 4-2=2。从而容易感受,当初分配 \(a_i\) 时肯定是越平均越好。由上,若把 1 分为一列,上述“尽量让含 1 的列元素和的最小值最大,这个值是多少”是 9;若分两列,则必然是各用 9 个 1,4 最好,值为 21;分三列,是 9 个 1,3,4,值为 24;分四列,值为 22。故答案下界为 24。
或者,更严格的证明是,分一列,为 9;分两列,必然两列分为 111114444,111144444,因为无法调整使之更优,为 21;分三列,其下界为 (1+3+4)*9/3=24,恰能取到;分四列,其下界为 (1+2+3+4)*9/4=22.5 下取整为 22,虽能取到,但不优秀。
下证实际答案也能取到 24。不妨 111333444 重复三遍,然后 222225555,222255555,这都是大于等于 24 的。每五个数字一组仿照上述方式填写,共 200 组,易知后面 199 组都比第一组要大,故能取到 24。
T-125-3
求 \(n\) 个点的无向图,满足不存在三元环和四元环,其最大边数。无需构造方案。
不妨选择双元限制试试:取任两个元素 \(i,j\),假如它们有边,那么为了防止出现三元环,它们...?假如它们没边,那么为了防止出现四元环,它们...?这里的刻画,其实挺自然的,如果没边,它们最多有一个公共邻居;如果有边,它们不能有公共邻居。这提请我们注意“公共邻居”这个数量。根据刚才的分析,这个数量不能超过 \(\frac{n(n-1)}{2}-m\)。另外,尝试用图度数介入数量关系的考察(比较常见。因为考察数量关系,所以常用度数、边数、顶点数等)。以节点 \(i\) 为主体,它作为别人的“公共邻居”恰好 \(\frac{d_i(d_i-1)}{2}\) 次。换句话说,题图必须满足 \(\sum \frac{d_i(d_i-1)}{2}\le \frac{n(n-1)}{2}-m\),又有 \(2m=\sum d_i\),故 \(\sum (d_i^2-d_i)\le n(n-1)-\sum d_i\to \sum d_i^2\le n(n-1)\)。
由柯西不等式,\(d\) 尽量平均时 \(\sum d_i^2\) 较小,因此不妨设出最大可能 \(m\),它必须满足 \(\frac{4m^2}{n}\le n(n-1)\to m\le \frac{n\sqrt{n-1}}{2}\)。当然,因为 \(m\) 是整数,所以要下取整一下之类的。
T-125-4 QOJ7236
先证一下正确性吧。像这种东西还是优先考虑一个数量,可以结合抽屉原理之类“平均”的东西。取数量为,所有集合两两交集大小。改换主体,考察每个元素被几个集合包含,设为 \(d_i\) 个,则上述数量就是 \(\sum \frac{d_i(d_i-1)}{2}\)。仍旧柯西不等式,为了让它尽量小那元素就得尽量平均,而我们知道 \(\sum d_i=n(n+1)\),故它最小是 \(n\frac{n+2}{2}\frac{n}{2}\frac{1}{2}+n\frac{n}{2}\frac{n-2}{2}\frac{1}{2}=\frac{n^2(n+2)+n^2(n-2)}{8}=\frac{n^3}{4}\)。另一方面,要求集合两两交集小于等于 \(\frac{n-2}{2}\),那就是要求该数量小于等于 \(\frac{(n+1)n(n-2)}{4}\)。因为 \(n^3>(n+1)n(n-2)\),所以我们证明了题目给出的那个性质。
但是如何查找呢?题目允许 \(O(n^2)\) 的算法。先枚举答案中的一个集合怎么样?关键就变为,能不能在 \(O(n)\) 时间内判断:是否有一对合法答案包含这个集合。不妨对每个元素计算“除了被当前枚举的集合,还被几个集合包含”,然后把这些值求和。如果和大于 \(n\frac{n-2}{2}\),那就意味着必然存在一对合法答案包含这个集合,我们再依次枚举答案中的另一集合,并做检查即可。总复杂度 \(O(n^2)\)。
T-126 P15653 26-3-16 S
先把图取反,转化为令这个图边数最小。只是为了方便叙述。
构造题就是,我再强调一遍,从数量关系刻画、能操作就操作、把暗中已经确定的东西变现、二级结构、dp、归纳。这个 \(k\le n-2\) 是很奇怪的,没想法吗?这暗示还是挺明显的。我一次操作,一定不会涉及到的元素,至少有两个。换句话说,如果我想要“某次操作不准涉及到某两个特定元素”,这是容易办到的。尝试一下二级结构,先随便操作一个,但要保证某两个特定元素 \(x,y\) 不被操作;再随便操作一个,这次保证 \(z,w\) 不被操作。然后再试试让两个操作集合有所接近(或者思考 \(k=n-2\) 的边界情况,这时恰好满足下面的优良性质),不妨令除了 \(x,y,z,w\) 以外,这两个操作集合都完全相同为 \(S\),满足 \(|S|=k-4\)。这样一个二级结构的效果为,反转了 \(x\to y,z\to w\) 还有 \(x,y,z,w\to S\)。这很不妙,我们对称一下,再搞一下二级结构 \((y,z,w,x)\),结果就仅相当于反转了这个四元环 \(xyzw\)。这才是真正有用的二级结构。
看看数量关系吧。关注一次操作对“全局边数和奇偶性”的改变情况,我们只关心 \(\frac{k(k-1)}{2}\) 的奇偶性;关注一次操作对“全局度数为奇数的点个数”的改变情况,我们只关心 \(k\) 的奇偶性。跟 T-125-1 有所类似,需要模四分组:
\(k\) 模四余三,则前一个值会变化。
\(k\) 模四余一,则两个值都不会变化。
\(k\) 模四余零,则后一个值会变化。
\(k\) 模四余二,则一次操作,上述两个值都会变化。
考虑四元环二级结构的作用,它并不会改变两个值。但是感受一下,它能把原图变成“任何满足两个值和原图相同的图”,严格证明使用欧拉回路。再猜一手,题目给出的 \(p\) 足够大。这样一来,我们 report 的答案,是不是就能算出了?分类讨论:
模四余三,则将奇度数点两两匹配连边,最终用四元环能消成“这些边”。
模四余一,先将奇度点两两匹配连边。若此时的边数和实际边数奇偶性不同,则再添加一个三元环(可抵消之前的配对边)。最终用四元环能消成“这些边”。
模四余零,则提前操作的效果是什么?能让后一个值尽量小。从而只需关注前一个值,若是一,则最终用四元环能消成“一条边”,反之消完。
模四余二,则我们可以提前操作几次,把原图变成“两个值均为零的图”,从而消成零。
这是因为在 \(k\) 为偶数的情况下,我们有办法将两个成对的奇度数点 \(x,y\) 变成偶度数点,而不改变其它的。我刚才说,\(k\) 是偶数,一次操作将会改变被操作集合的所有元素的度数奇偶性。因此需要两次操作的操作集合异或结果,是两个点,那么操作 \((x,S),(y,S)\) 就行了,其中 \(|S|=k-1\)。在 \(k\) 模四余二、三的情况下,如果希望改变总边数奇偶性,随便操作一次就行了。
所以实际上已经给出了一种构造方案:先提前操作几次,尽量消去奇度数点、处理总边数奇偶性。然后就一直操作四元环,直到四元环操作不优(无论操作哪个四元环,都不会减少总边数)。但是我不太会动态找合法四元环,时间复杂度炸了。
为了找出所有合法四元环,归纳构造。不妨按照编号从 \(n\) 到一,把涉及到当前元素 \(i\) 的所有操作都搞完,必须在 \(i-1\) 次操作内搞定,把问题递归成 \(n'=i-1\) 的子问题。换句话说,进行所有涉及 \(i\) 的操作后,大概率 \(i\) 不再和别人连边,或者只连很少的几条,这些边会被保留到最后。具体一点,不妨按照分类讨论部分的“连边”方案,真的连边造个“新图”,我们的目的,转为把图真的消成“新图”的样子。操作方式如下(这个算法称作“方法”):
若需要且能够进行提前操作,就先尽量操作。
然后归纳构造,按照编号从 \(n\) 到一扫描 \(i\)。每次不停地消涉及 \(i\) 和它邻域 \(u,v<i\) 的某个四元环,用四步,删除了 \(i\to u,i\to v\) 两条边(假设四元环为 \(iuvx\) 则也反转了 \(u\to x,v\to x\) 的边。我们要求 \(x<i\),因为是归纳构造嘛)。要求,这两条边均不属于“新图”。容易证明,这样一直消的结果,也肯定就是“新图”,因为提前操作已经把各种特殊情况都处理了。不过有特殊情况,就是 \(k\) 为偶数,\(x\) 度数为奇数,但邻域内最后剩下的点 \(y<x\) 度数为偶数的情况。那么 \(x\to y\) 必然不在“新图”上,找出 \(x\) 在“新图”上的实际配对,等待扫描到 \(y\) 时调整一下就行了。
操作次数是超了的,不过 \(n^2+10n\) 大概是能够通过。接下来为了得满分,抛弃四元环和提前操作,也抛弃显式建立“新图”,转而直接归纳。
按照编号从 \(n\) 到一。先不断成对消 \(i\to u,i\to v\) 满足 \(u,v<i\),可以操作 \((i,u,S),(i,v,S)\)。要求 \(S\) 中的元素也小于 \(i\),换句话说这个策略只有 \(i>k+2\) 才有效。如果邻域剩下单点 \(u\) 满足 \(i\to u\),且 \(k\) 是偶数。只需在处理一切有关 \(i\) 的操作之前,提前操作一下 \((i,S)\) 改变 \(i\) 度数奇偶性,也是只有 \(i>k+2\) 才有效。
这样一路操作到了 \(i=k+2\)。现在待处理子图是一个 \(n'=i=k+2\) 的图,用“方法”直接处理。本来步数还是要超,但是注意到 \(n'=k+2\),所以本质不同的原操作恰好有 \(\binom{n'}{2}\) 种,因此只需将涉及的操作异或去重,即可保证不超限。
对于我来说,这最后一步是难以想到的,先欣赏吧。这个操作异或去重呢,我认为也是要作为 trick 背诵的,因为自己推理不出来啊。
T-127 CF1876G 26-3-17 B+
若只有一次询问。注意到操作涉及的元素具备一定方向性,这个方向性是在位置轴上的。故从 \(r_j\) 向 \(l_j\) 扫描一个值 \(i\),每次操作若干次 \(i\) 直到 \(i\) 符合条件。现在有多次询问,可以仍旧倒序扫描位置轴,内层维护询问轴,就是碰到 \(r_j=i\) 则插入一个询问;碰到 \(l_j=i\) 则查询答案。具体来说,\(\mathrm{ans}_j\gets \mathrm{ans}_j+i\lceil\frac{x_j-a_i}{2}\rceil,x_j\gets x_j-\lceil\frac{x_j-a_i}{2}\rceil\)。转换主体从函数的角度看,一个 \(a_i\) 对所有 \(x\) 的作用,是一个两段分段函数,而且函数单调递增。换句话说,除了插入/删除新询问造成影响外,其余情况下 \(x_j,x_k\) 的相对大小关系并不变化。
然而,上取整太难了,因为你不敢讨论奇偶性;至于维护 ans,本来可能想着历史和,但实际上更是天方夜谭。就是说,平衡树打 tag 维护不了这个东西,那咋办。数据结构题我多次强调过缩连续段,尤其是具备某单调性的时候(因为单调性暗示着两个轴地位一致。一般而言,这时候的连续段,就不只是在一个维度上,而是同时在多个维度上,故性质更优良。以本题为例,连续段不仅是值域连续段,如果绘制二维图,它还是位置轴-值域轴上的类矩形)。事实上,每次暴力处理所有的 \(x_j>a_i\),合并值相同的 \(x_j\),复杂度就是对的,用带权并查集处理一下即可。
如何证明?感受一下操作的良好性质,除了保持单调性以外,还有什么?取类极差势能量,应该是一直减小的。取势能量 \(\sum \log (x_j-x_k)\) 表示(值域上)相邻两项差的对数和,则每次暴力处理,都必然让势能量减小一。故复杂度 \(O(n\log n\log V)\)。
T-128 AGC018F 26-3-17 A+
感受一下,不用填绝对值太大的数,只需填 \(\pm 1,0\) 即可(是个 trick 吗?好像如果值域过大,乃至大到无限,或者值域是允许取任意实数相当于暗含无穷。你就得尝试把它降一降,要么用离散化,要么用拉插,要么就是指出值域不用那么大,只需使用几个特殊的值/较小范围内的值就够了)。若只有一棵树。不妨按照对树的处理习惯,自底向上构造,在处理 \(x_i\) 之前,已经分配了其子树内所有点的值。那么已知 \(x_i\) 的若干儿子,每个节点的子树和都是正负一。用取反的调整方法(令子树内所有负一和一变成对方),可以让和为正负一的子树个数尽量平均。如果当前节点有偶数个儿子,那当前节点可以填正负一;反之,当前节点填零就行了。
我说过,构造题要把已知东西变现。对于两棵树的情形,首先,每个编号在两树中的节点度数奇偶性必须一致,否则无解(证明:认为正负一都是奇数,偶数个奇数的和,与奇数个奇数的和,奇偶性必不相同,故矛盾)。然后,若节点度数为偶数,则这个编号 \(i\) 对应的 \(x_i=0\)(这节点的子树去根和,就是奇数个奇数的和,是奇数。刚才说 \(|x_i|\le 1\),故 \(x_i\) 只能取该范围内唯一偶数)。但是接下来有点难以进行,这是因为限制加在“和”上,而且有两个互不相关的轴(树),不存在一致的偏序关系(方向性)。没有偏序的时候,尝试图论。
对问题限制的刻画,不妨照抄题意,但要利用上已知信息“偶度点分配零”。换句话说,对任一棵树上的任一节点(因为根比较特殊,为了下文奇偶性讨论的正确性,不妨建立虚根只向根连边,下文的一切讨论都视作建立过虚根),其子树内“选正一的奇度点”与“选负一的奇度点”个数之差的绝对值为一。好奇这个绝对值是不是必为奇数,显然是,因为对任一子树,子图内的点度数和(假设根向外的边不断开)为奇数,从而奇度点有奇数个。不妨称“正一点”为“黑点”,“负一点”为“白点”,则要求对任一子树黑白点个数尽量平均。
“尽量平均”就该想到欧拉回路,因为欧拉回路保证了对任一点,出入度尽量平均。事实上,欧拉回路有更强的结论——对任一连通子图,出入度也是尽量平均的。目标是让黑白点数平均,这要求我们把子树内的黑白点,和子树连通子图的出入度,做一一对应。这提示我们平行地,分别独立建两棵树的图(共计 \(2n\) 个点)。并且让奇度点连出异于原树边的,一些大小为一的边,作为“子树连通子图”的出入度备选项。
第一个想法,奇度点向同一平面(同一棵树)内的点连边。这不可能,只需将这两个点的 lca 选取考察“子树连通子图”,则该子图少了至少一条“该向外”的边。所以奇度点只能向垂直于图平面的方向连边,也就是向另一平面连边。具体来说,分别找出两个平面内的奇度点,当成完全二分图,随意找一个匹配连上即可?注意编号相同的元素填写的值必须相同,所以令两个平面内编号对应的点配对起来,才是正确的。
最后检验画出的最终图,到底有没有欧拉回路。这要求图必须连通,且没有奇度点,肯定是满足的。跑完欧拉回路,如果一条“对应连边”从树一到树二,就给他分配正一;反之分配负一。
欧拉回路,我们借这个题复习了一下。如果遇到关键词“平均”“度数奇偶性”,就该有所敏感了。要求每条边恰好经过一次,或者要做边定向,使得每个子图的出入度数平均分配,就要想到欧拉回路,这是因为欧拉回路上一个点必然是进来 \(\frac{d}{2}\) 次又出去那么多次。需要先补全一些边,保证原图存在欧拉回路,再跑算法。举一例,T-126 对于四元环能任意消的证明,就是借助欧拉回路。是因为当时根据点的“度数奇偶性”做了分讨,所以想到的。
T-129 P12055 26-3-18 A+
读者可能注意到,我对 ad-hoc 开战了。是这样的,注意到对于 ICPC 风格的题目我并不擅长,所以我跳出了经典 CNOI 的舒适区,接下来一段时间,神秘题目可能比较多,大部分来自 CF,AT,QOJ。而 trick 一词的频度出现也明显提升,并且我很罕见地在 Exemplary Examples 中插入我未完全掌握的题目。解释一下,对于一道题目,了解做法是最基础的;了解做法并能背诵其中的 trick 是其次;了解做法并能根据体系逐步推出,或者根据本题扩展体系然后能逐步推出是最好,我称之为掌握。但是现在体系还不够完善,对它的扩展,是需要补充新的养分。所以有一些步骤我未能完全掌握,先将其视作真正需要背诵的 trick 也有一定合理性,毕竟我现在认识到 trick 也是 OI 必不可少的部分,trick 也是体系的核心部件之一。经过对一些经典 trick 的背诵,以及对部分题目的自主推理和深度思考,我还是有信心让体系更加强壮。
首先我们写一个区间 dp 作为暴力,可用于打表。
倒序考虑,最后一步必为 1?1:x,0?x:1 二者其一。这是构造题,先把我们已知的变现,从而无需考虑 11 开头或者 0 开头且 1 结尾的串了。只需关注形如 10x,0x0 两种串。
再想想已知什么?11x=1,0x1=1,当然需保证串长为奇数。这是一个强大的二级结构,亟需变现。
对于 10x,从边界元素考虑,只需操作首位三个元素得到 0 做新开头,就能转化为 0x0。故只需讨论形如 10x0 的前者串。倒序考虑,最后一步如果形如 1?1:x。我在开头有现成的 1,先假设把它保送到最后一步前(还是在把已有的变现),那么只能是 x=a+b,1?(0a):(b0) 的方式。因为要求 0a=1,从二级结构出发,如果 0a=0y1 就已经成功。换句话说只要偶数位有一就赢了。很自然地考虑偶数位没一的串,打表其实是能看出无解。来证明一下,还是要变现,我刚才说只要偶数位有一就赢了,那能不能操作一次使新串偶数位有一呢?其实,对于任何(不限于 10x0 的串)以零结尾且偶数位没一的串,无论如何操作偶数位上都没一,并且仍以零结尾。换句话说这种串是自我归纳的,所以最后只会得到 000,100 其一,从而只能得到 0。
对于 0x0,尝试把它转化成大家所熟悉的(实质上还是做变现),找出第一个奇数位上的一并缩前缀,就能得到 10x 的情况。换句话说,只要存在一个奇数位一和其后的一个偶数位一,就赢了。打表是能看出其余情况无解,证明也类似,不存在“一个奇数位一和其后的一个偶数位一”的串仍旧是自我归纳串,最后只会得到 0。
好题呀,好就好在充分表现了“变现”的功用。我再解释一遍,“变现”就是把我们已知的信息、已知的二级结构先直接用上试试,看看这样直接用上,能够解决哪些情况,那么这些情况未来就不用考虑了。特别是,把一种情况转化成另一种已经解决的情况。关注哪些情况容易做这种转化,哪些情况又一定不能做这种转化,而这又自然地引出“自我归纳”的理论。“自我归纳”就是指,对于一种属于类别 A 的状态,无论如何操作它,结果都仍属于 A。在本题中,取 A 为“未被解决的情况”,结果发现“自我归纳”成立,所以无论操作多少次,一个类 A 内的状态都不会变为“已经解决”的情况。
另外,我感受了一下,既然“不喜欢”零,故可把零连续段缩合成奇偶性不变的尽量短段,形如 0,00 之一。我们只需讨论所有的零连续段长都小于等于二的串。这个结论看来是正确的,但是对解题帮助比较小。
T-130 CF1942H 26-3-18 B+
如果没想到二分图,这题也是能做的,我们用代数推导绕过难点,剩下的就本质相同了。
假如没有修改。因为它说了可以改变操作顺序,所以这个顺序轴是没有用的,关键的只有每个点 \(x\) 生长、收获多少次,记录这两个值分别为 \(p_x,q_x\)。在树上,我们合并子树、从下往上贪心。贪心就是记录最优解的信息,尤其是我们站在子树外时,需要关心的子树内信息。有三部分,一部分是“亏欠多少桃子”(可能是收获导致的,也可能是 \(b_x\) 导致的),第二部分“盈余多少桃子,专门用来抵消收获”(不含第三部分),第三部分“有多少盈余桃子可以加给子树根的父亲”。核心代码如下(F1,F2,F3 分别代表 \(x\) 的儿子们的第一、二、三部分个数之和),其主要策略是,先用儿子们传上来的第三部分抵消 \(b_x\),再用 \(p_x\) 抵消 \(b_x\),再用第二、三部分抵消 \(q_x\),最后用 \(p_x\) 抵消 \(q_x\)。
int tt=min(b[x],F3);
F2+=F3-tt;
int P=p[x]-(b[x]-tt);
F2-=q[x];
if(F2<0){
P+=F2;
F2=0;
}
F1+=P;
if(F1>0){
F3=F1;
F1=0;
}else F3=0;
f1[x]=F1,f2[x]=F2,f3[x]=F3;
这种在树上修改信息的 dp 题目,大概率是 ddp 嘛。我们的矩阵乘法大概率是 min,+ 之类的,所以对上述转移过程做变形,结果如下:
f1[x]=min(0ll,F1+p[x]-b[x]-q[x]+min(min(b[x],F3)+q[x],F2+F3));
f3[x]=max(0ll,F1+p[x]-b[x]-q[x]+min(min(b[x],F3)+q[x],F2+F3));
f2[x]=max(0ll,F2+F3-min(b[x],F3)-q[x]);
有 min 还有 max,这不好做,因为纯 min,+ 矩阵是不能给元素乘上负系数的,所以纯 min,+ 不可能实现 min,- 或者 max,+ 矩阵的功能。设计一种全新的矩阵乘法,又太难了。回忆对 dp 的优化方法,可能奏效的是改换状态为 g1,g2,g3,G1,G2,G3,目的是,表示转移式的时候保证 G1,G2,G3 前的系数都是正一,而且所有转移式中,只用到 min,max 中的一种。注意到 f1,f3(下文省去 [x])形式很对称,又看到 f1 的转移式子中只含 min 和 +,是三个式子中整端的一个,不妨定义 g1=f1,g2=f1+f3。但是这真能转移吗?
在处理多重嵌套的 min,max 式子的时候,我们常常把嵌套拆开,变成仅一层的。正如处理多重嵌套绝对值式子时常常把嵌套拆开而只关心元素前的系数一样。在此拆开 g1 的转移式,它是 g1=min(0,F1+p-b-q+b+q,F1+p-b-q+F3+q,F1+p-b-q+F2+F3)。看起来不错,因为 G2=F1+F3 出现了,从而容易猜到 g3=f1+f2+f3。秉着这个想法,整理一下转移式。
g1=min(0,G1+p,G2+p-b,G3+p-b-q)
g2=f1+f3=min(G1+p,G2+p-b,G3+p-b-q)
g3=f1+f2+f3=min(G1+p,G2+p-b,G3+p-b-q)+max(0,F2+F3-min(b,F3)-q)
=min(...)-min(0,min(b,F3)+q-F2-F3)
=min(...)-min(0,q-F2,b+q-F2-F3)
刚才的转化用到了 \(\max(A,B)=-\min(-A,-B)\),我们在 T-050 见过的。到这一步,就需要你的一点数学直觉,看这个 q-F2,b+q-F2-F3 特别像 F1+F3+p-b,F1+F2+F3+p-b-q 的翻版,不妨往这边靠。
g3=min(G1+p,G2+p-b,G3+p-b-q)-min(F1+F2+F3+p-b-q,F1+F3+p-b,F1+p)+F1+F2+F3+p-b-q
=F1+F2+F3+p-b-q
=G3+p-b-q
好了,有这些好看的式子,就可以写出 min,+ 转移矩阵了,直接 ddp 即可。以防忘记,重申一遍,树剖 ddp 是,每个节点接受自己重儿子传上来的 [g1,g2,g3],与自己的轻儿子们的信息做合并得到本点的 [G1,G2,G3],然后算出本点的 [g1,g2,g3] 向重链上端传递。如果没有上端,自己就是轻儿子,就把信息送给父亲。其中从重儿子的 [g1,g2,g3] 得到本点的 [g1,g2,g3] 的过程可以看作一次矩阵乘法,因此用重链线段树维护区间转移矩阵的积。每次修改只需改变 \(O(\log)\) 个转移矩阵,就是本点的,还有本点到根链上一切轻儿子的父亲们的。
当然,如果把问题当作匹配,利用扩展二分图霍尔定理,最大匹配等于 \(N-\max_S |S|-|N(S)|\),所以只需描述最优的 \(S\),这个描述法对应的 dp,就直接是换元后 g1,g2,g3,G1,G2,G3 的转移,十分神奇。所以我一再强调,我的办法通常不是最快的,它到终点得绕绕路,而我的目的是,在想不到捷径的时候,尽量通过体系让路绕过去。但这并不是说捷径就不重要了。
T-131 QOJ9918 26-3-18 B+
两个轴,一个是时间,一个是树。得啦,我们先把树相关东西总结一下。如果把树轴放外面,最常见的思路是按照 dfn 序扫描、按照深度正/倒序扫描、合并子树信息,不常见的有按节点编号扫描等。如果把树轴放里面,常见的有即时维护虚树、重链剖分并即时维护线段树、dfn 序拍平以维护子树加和信息等(链改可视为到根链改,从而对称成子树操作)。
本题如果把时间轴放外面,就只能选择重链剖分,而这是不可能处理的。故把树轴放外面,内层维护时间轴。采取子树合并-线段树合并的办法,内层维护出当前节点依时间顺序的涉及一操作。然后处理当前节点的涉及询问,二分之后就是,将当前线段树上某段区间的元素顺序拉出来组成序列 \(a\),问:选择 \(a\) 中若干元素,不准选相邻的,和最大是多少,这是经典 dp 问题,用 \(f_{0/1}\) 处理。不过本题要在线询问一个区间的答案。
我说过,多次询问的 dp,或者带修的 dp,大概率是 ddp,小概率是猫树分治等数据结构题的常规处理办法,或者状态之间具备递推关系。本题用 min,+ 的二乘二矩阵 ddp 处理即可。
T-132 CF1515H 26-3-18 A
两个轴,值域和时间。只能把时间放外面,内层值域轴必然是用 01trie 维护。感受一下,元素只会合并而不会分裂,故暴力合并是正确的。假设只有异或操作,你就会发现常规线段树的给 \(O(\log)\) 个子树打 tag 是不能处理本问题的。这种情况下可以做线段树分裂(我这是第一次做线段树分裂的题目),变为全局操作(也就是给待处理区间新建立 \(O(\log)\) 个虚点,从而具备一棵完整 trie 的结构,于是能够处理 tag),然后线段树合并回来。线段树分裂的复杂度是一次 \(O(\log)\) 的没有问题,而线段树合并每递归一层就会减少全局的一个节点,故其总复杂度为 \(O(n\log V)\) 也没有问题。这种分析“全局节点个数”为势能量从而计算复杂度的,在数据结构题目中很常考,例如 QOJ9559 P5494。我认为线段树分裂能做的,大多用平衡树(带交并)也能解决。
那么处理分裂开来之后的部分。异或操作直接打 tag。至于或和与,刚才说了需要暴力合并元素,这明显指向势能线段树。我介绍过,势能线段树就是应用于如下情形:某种特殊操作(一般是类单点操作)已知总计进行很少次(一般是 \(O(n)\)),所以在做区间修改的时候,要分别检索当前节点的两个儿子,其子树是否存在“需要进行特殊操作”的节点,如果有,就必须暴力递归该儿子。从而,为了进行一次特殊操作,我们仅递归了 \(O(\log V)\) 次。
以或为例,或的作用是,让某些层节点的左子树与对应右子树合并。假设当前递归到了某节点,比本点深的“需合并层”用集合 \(x\) 表示。“需要进行特殊操作”的含义应该是,对应子树内存在某深度为 \(d\) 的节点满足“它同时具备左右儿子”(称之为合法),而且 \(d\in x\)。对于树上节点,不妨动态维护当前子树内的合法 \(d\),递归到本点时,\(O(\log)\) 查询一下即可了解是否应该向下。如果无需向下,就意味着本点的子树内没有合并,给它打一个或的 tag 即可,作用就是让一些左子树旋转到右边,和异或操作有所类似。
与也类似,那么现在有三种 tag,涉及的问题只有 tag 下传。多 tag 问题,我们在只有加和乘 tag 的线段树问题中介绍过。这种问题如果能够解决,就意味着一个操作序列,可以被压缩成顺序确定的“tag 种数”次操作,操作的先后顺序需要你来确定,必须合适。举例来说,对于只有加乘的情况,我们把操作序列压缩成先乘 \(a\) 再加 \(b\)。这类问题,只用考虑合并 tag 的时刻,例如两个操作时就是问“任意元素先与 \(a\) 做操作 A 再与 \(b\) 做操作 B 再与 \(a'\) 做操作 A 再与 \(b'\) 做操作 B 的结果,等于先后与 \(a'',b''\) 做 A,B 的结果,求这个 \(a'',b''\)”。
经尝试,本题中的操作顺序应为与,或,异或。记点 \(x\) 的 tag 按顺序分别为 \(a,b,c\),受到上面下传的标记 \(a',b',c'\) 的作用。合并时,按顺序先传下来的是与标记 \(a'\),就把当前维护的 \(b,c\) 的对应位置都改成零 b&=a',c&=a',然后令 a&=a';上面传来一个或,就令 c&=(~b'),然后令 b|=b';最后传来异或,就令 c^=c'。
T-133 QOJ13024 26-3-19 B
假设只有一组询问。先用一操作把所有元素对二取模,而且从今往后都要对二取模。用调整法,一个状态能够用二操作调整到更优,当且仅当在非末端两个的位置,存在一个一紧跟着一个零。这是因为,如果那个零后面跟的是一,那么操作后两个一叠加就变成偶数跑掉了,零的个数增加;反之零的个数也不会减少。从而,优秀的最终状态形如 000000111111,当然最末端两个位置需要特殊处理。
法一,取势能量 \(\sum ia_i\),这个东西只会增大,而且奇偶性不变。能够看出,无论哪种操作都是在把靠左边的值移动到右边,具备偏序关系,故不妨从左向右扫描一个值 \(i\)。如果 \(i\) 增加一时,发现 \(a_i=0\),那我肯定要操作二 \(i\),进而 \(a_{i-1}\) 就变成零,可以进行操作二 \(i-1\) 等等。这些操作的具体结果就是,令 \(i-1\) 及以前的一连续段(易知只有一个,在扫描过程中不妨称作“当前连续段”)向右平移两个位置,如果 \(a_{i+1}=1\) 就把它变成零。我在此推荐大家自己画个零一串的小样例并模拟一下。
关心的基本上就是,从左到右扫描一遍之后,那个“当前连续段”的长度。接下来就看你的喜好,我比较喜欢连续段,所以把原有的零一连续段缩起来了,这时再跑从左向右扫描 \(i\) 的过程,就相当于:如果第 \(i\) 个一连续段(长度为 \(a\)),和当前连续段间(长度为 \(b\)),间隔的零个数为偶数,那么当前连续段应变为 \(a+b\);反之,应变为 \(|a-b|\)。至于多组询问,上线段树做信息合并就可以了。
法二,比较神秘一点。对于零一序列,关注它的差分、前缀和是很常见的,类似的还有翻转偶数位。本题中,如果关注前缀和序列 \(s\),那原串上的操作 0100->0001,0101->0000 就会变成 0111->0001,0110->0000。换句话说,把前缀和中的两个相邻的相同位 \(i,i+1\) 异或了一,不过这还要求 \(s_{i-1}\neq s_i\)(因为 \(a_i=1\))。知道最终的前缀和序列,它是形如 0000001010101 的,如何算答案呢?只需统计里面一的个数就可以了。
不过并不好直接算。我不知道他怎么想到的取势能量“奇数位置一的个数减偶数位一个数”(也许是看到答案是零一相间的?),这个量在每次操作中不变,而答案恰好就是它!所以对于区间查询,直接算区间内“奇数位置一的个数减偶数位一个数”,就可以了。
T-134 CF2164G 26-3-23 A
首先它是统一询问统一回答,所以只需模拟“提出询问-根据全部信息还原结构”的过程即可。每次询问排列,所以第一次询问直接问 1 到 \(n\) 的排列一定是对的。这告诉我们,对于每个节点 \(i\) 来说,编号小于 \(i\) 且和它有连边的点个数。这看起来没什么用,但它类似度数,我能不能得到度数序列呢?对称一下,再问 \(n\) 到 1 的排列,加起来即可。
类似于 T-116-1,树结构的构造/还原,就是需要知道每个节点的父亲。特别地如果是无根树(父亲无定义),一般从叶子节点开始归纳构造,先找出叶子节点的“父亲”,然后删除叶子节点。我说过构造/交互题先感受步数限制,看到 31 大约是 \(2\log_2 n\) 的样子,这提示类二进制构造。序列上的二进制,似乎提示分治。不妨先进行第一步分治看看。也就是询问 1 到 \(n\),然后询问“mid 到 \(n\),1 到 mid”的拼接。这两者对比可得,对每个点,它连向分治对侧的边数。此信息落到“叶子节点”这一边界元素上,就是它的“父亲”是否位于分治对侧。
那么放弃分治,转而枚举一个二进制位 \(i\),将元素按照编号在这一位上是否为零分类,同类内按照编号排序。于是问 0000011111,1111100000。即可知道所有叶子的“父亲”在第 \(i\) 位上是否是一。故知道了所有叶子的“父亲”。更进一步地,这些信息足够进行归纳构造了,总步数 \(O(2\log_2 n+1)\),略微超限。总结一下,编号按照二进制位重写,并按每位零一分组,然后考察组间/组内关系,是应用场景与分治类似的重要技巧。
为了通过本题,采取对数构造换底,这也是常见策略。若以三为底,仿照上面,询问 111122223333,222233331111,333311112222,即得 $O(3\log_3 n+1) $ 的做法。
T-135 CF2207G 26-3-23 B
解是一个类似图的东西,先关心它有没有特殊性质,看出它不能有环,于是是一个森林。
感受步数限制,\(\frac{2}{3}\) 这种分数一出来,就是在暗示分组构造,或者做法拼接平衡,我们在 T-077 介绍过。网格上比较著名的分组方法,就是棋盘染色,本题需要三染色,也就是按照 \(i+j\) 模三分组。接下来有两个限制,一个是井号必须被全部包含,第二个是最大的两组大致被包含。分步满足,先满足第二个,我们直接把那两组全选,它们必然是阶梯状的,可以构建森林。然后满足第一个限制,加入属于最小组的井号,在已有的图上做调整,使得图中没有环。从特殊到一般,没有环起码得没有四元环吧,可以在绿色点中选一个删,并在黄色点中选一个删,删完后,其实图中就没任何环了。注意每个井号四相邻不存在叉号,所以做法是对的。证明很简单,关键是要注意到 \(P\) 中不含井号的价值。

T-137 QOJ17249 26-3-23 A
计数题,一般就是 dp,组合,容斥,生成函数自由搭配。被十一整除的数满足,偶数位数码之和,减去奇数位数码之和,模十一余零。那么数码相同的元素地位也应相同,但是直接 dp 无法接受,也无法直接生成函数优化。计数题目中,对于地位相同的元素,有常见技巧是把它们强制地位不同,但最终除以某个数防止算重。本题里,如果强制数码相同的元素地位不同,则描述法应为,把每个元素划到两个集合之一里。答案的生成函数表示很明显是:
其中 \(x\) 常规多项式乘法,\(y\) 模十一次方循环卷积。本题中 \(y\) 维度很小,因此是一个从属的状态,类似于 T-101-2-3-3 不太重要。主元是 \(x\),我们运用求导法得系数递推式。
所以说求导法的应用条件是,能够把 \(F',F\) 用少项式联系起来。
T-138 26-3-24 A
有一个长度为 \(n\le 300\) 的未知排列 \(p\),每次你可以给交互库一个排列 \(q\),交互库将返回排列 \(r\)(满足 \(r_i=p_{q_i}\))的置换环数目。询问次数限制为 \(2200\)。
跟 T-134 一样,先询问 \(q_i=i\) 准不会错,此时 \(r_i=p_i\),设返回答案为“初始值”。关注步数限制,它接近但小于 \(n\log_2 n\),怎么回事呢?我稍后解释。因为要找出初始排列,故尝试询问做某个小调整后的结果。例如在初始排列基础上,交换 \(q_x,q_y\) 并询问。如果 \(x,y\) 在 \(p\) 中位于同一置换环,则返回值比初始值大一;反之比初始值小一。经过 \(O(n^2)\) 次询问,能够得到每个置换环内的元素组合情况。
尝试归纳构造,和 T-131 的树很像地,试图把某个 \(p_i\) 求出,从而把 \(i,p_i\) 合并起来,这就减小了规模。那就要关心 \(p_i\) 与“和 \(i\) 在同一置换环内的其它点”的区别,这个区别就是,若在 \(r=p\) 的基础上把 \(q_i,q_{p_i}\) 互换,则 \(r\) 中 \(p_i\) 所在的置换环大小变成了一。从而得到 \(O(n^3)\) 的做法。但是没有优化空间。
排列问题可以关注逆排列,逆排列的信息和原信息等价。希望求出逆排列 \(h\) 满足 \(h_{p_i}=p_{h_i}=i\),你看这个 \(h\) 和 \(q\) 的地位好类似,而我们在询问过程中时时刻刻知道 \(q\) 的。所以如果某次询问的时候发现返回值是 \(n\)(全部是自环)那么 \(q=h\),即知道了答案。问题转化为构造合适的 \(q\)。接下来为了表述更清晰,我做如下题意转化,这不是必要的:有一个未知初始排列 \(p\),令排列 \(r=p\),每次可以交换 \(r_x,r_y\),或询问 \(r\) 中置换环个数,只对询问次数有限制。请找出一个办法把 \(r\) 变成全是自环的排列。
每次询问的答案“置换环数”是明显的势能量,有它就知道问题是否被解决。若还没有,那么说明在 \(\binom{n}{2}\) 个数对中,存在一对,其中二者仍处于同一置换环。只需要在大约 \(O(\log n)\) 复杂度内,找出一个合法数对并交换它们,就能让置换环数增加一。想到分治,假设已知在集合 \(S\) 里面存在至少一个数对,称之为“合法集合”,尝试把它划分成两个大小折半的集合 \(P,Q\),然后判断 \(P\) 是否为合法集合,如果是就递归下去,规模折半;随机选择 \(P\),则有 \(\frac{1}{4}\) 概率成功。共期望 \(O(4\log n)\) 次找出一个数对。问题就是,如何在一次询问内判断集合 \(S\) 中是否有位于同一置换环的元素。不妨按照任意顺序将集合排序,然后依次交换 \(q_{S_i},q_{S_{i+1}}\)。如果交换后的返回值,与换前值的差不是 \(|S|-1\),那么 \(S\) 显然是合法集合。
这类问题常常可以,自己把排列随机打乱一下,减少极端数据的影响。也就是加上一个随机基底排列 \(s\),在本地维护 \(q'\),但是每次询问都要问 \(q=s_{q'}\)。但是在本题中不适用,因为随机排列的期望置换环数是调和级数 \(\sum \frac{1}{i}\),非常小。经过卡常,分治做法仍不能通过。
关键在于整个数对都不知道,这就需要随机化分治的办法。如果已经确定数对中的一个元素就好办了。那么归纳构造,每次把涉及到编号为 \(i\) 元素的数对都搞定怎么样?钦定 \(i\) 是数对中较大的元素,从小到大扫描 \(i\)。这样,就时刻保证前 \(i-1\) 个元素间不存在两个处于同一置换环,于是我们二分一下找出在编号 \(<i-1\) 的元素中,和 \(i\) 当前处于同一置换环的元素(若位置 mid,满足 \(S=[\mathrm{mid},i]\) 是合法集合,则那个元素的编号大于等于 mid),即可做到 \(O(\sum \log_2 i)\)。
未知排列的可能性为 \(n!\),若每次询问恰好得到一个 bit 的信息,则经过 \(\log n!\) 次就能求出该排列。所以这个复杂度在未知排列问题中或许常见。
T-139 P12920 26-3-24 B+
前两个子任务比较简单。本题共三个轴,值域轴、横纵两轴。值域轴显然放外面,每次查询可能是在上面做二分之类的。权值形如 \(c_{i,j}=\min(a_i,b_j)\)。故对于第三个子任务,每次询问把所有 \(a_i,b_j\) 暴力求出,然后丢到堆里面排好序,并处理一下即可做到 \(O(qn\log n)\)。
对子任务四,做法跟权值单位数有关,大概率是 \(O(1)\) 或 \(O(\log)\) 减小几单位权值。我们还是希望对每次询问分别扫描值域轴,连续地处理所有权值为 \(i\) 的贡献。假设刚刚处理了权值为 \(i-1\) 的所有元素,其实可以递推找出权值为 \(i\) 的所有元素,因为它们必然在某个权为 \(i-1\) 的元素的四连通向上,这就用 bfs 做到了大致 \(O(\sum c)\),但必然不能通过。类似于子任务三,缩一下连续段,把一列、一行元素统一处理(并剔除已知权值比当前 \(i\) 小的元素。这个数目可以通过之前处理过了多少列多少行算出),做到大致 \(O(qn\log n+\frac{\sum c}{n}\log n)\)。
对整道题,数据范围是 \(10^5\),尝试根号。根号分治,可以注意无论行列,空隙只有 \(O(\sqrt n)\) 种,或者大于 \(\sqrt n\) 的空隙只有 \(O(\sqrt n)\) 个。
本题中元素过多,不妨合并连续段,但如果仅把值相同的元素并段,似乎段数仍太多。把贡献来源相同的元素并段,如图四种颜色代表四个段

显然只有 \(O(\sqrt n\times \sqrt n)\) 种本质不同的段,以这些段为主体,给值域轴(第 \(i\) 个位置维护权值为 \(i\) 的元素个数 \(c_i\))贡献,每个段就相当于给 \(c\) 数组加上一个前缀等差数列。要维护修改,每次最多有 \(O(\sqrt n)\) 种段的个数,发生了变化。所以相当于 \(O(n\sqrt n)\) 次加前缀等差数列,只好分块值域轴去平衡,改成在头块、等差数列终止点打标记,单次 \(O(1)\) 的。
处理查询,允许单次 \(O(\sqrt n)\),这就很明显了,是值域分块代替二分。一样地扫描值域轴,一个块一个块地跳,需要 \(O(1)\) 求出块内 \(\sum ic_i\),在知道等差数列标记等东西的前提下,是容易的;当跳不过当前块(预算余量不足块内总价值)时,改为在块内一个一个跳,直到答案位置,也是容易的。做到 \(O(n\sqrt n)\)。
所以说,元素个数极多的情况下,大概率需要并段,创造新的元素。老生常谈,需要关注权值的计算,一个段内的权值必须得好算,所以一般来说段内权值都相同。但是较特殊的情况,例如本题中“同一段的贡献之和容易计算”是通过“权值来源相同”来处理的。所以,找出合适并段方法/合适元素的一般方法应该就是,关心题面给定元素的权值是如何计算的,如果这个算法中存在的“权值来源”,并把“权值来源”相同的元素并段。
T-140 AGC010D 26-3-24 A
公平组合游戏:在任意确定状态下,所有参与者可选择的行动完全相同,仅取决于当前状态,与身份无关;博弈中的同一个状态不可能多次抵达,博弈以参与者无法行动为结束,且博弈一定会在有限步后以非平局结束。
本题属于不能应用 sg 函数的公平组合游戏,再结合数据范围,必有关键结论。取势能量 \(\sum (a_i-1)\),它的奇偶性非常重要,如果没有除以 gcd 的操作,那么这个奇偶性直接决定胜负。但如果除以的 gcd 是偶数,那么上述势能量的奇偶性可能改变。想要 gcd 是偶数,就必须要所有数字都是偶数。直观地感觉,想让 gcd 是偶数有一定难度。
对于既得利益者来说,他肯定不希望改变现状,他只需要维持势能量的奇偶性不出岔子,或者加强条件:没有人能够除以偶数 gcd,那他就赢了,而这是容易的,因为他拿到手的状态必不全是偶数(因为这些数字 gcd 等于一),他让一个偶数减一,则给对方的状态就包含至少两个奇数,对方不能把状态变为全偶数。
那么,处于劣势的一方必须得是先手才可能改命,这个时候全局还必须只有一个奇数,他只能操作那个奇数,然后把状态给对方。这样的过程至多进行 \(O(\log)\) 轮,总复杂度 \(O(n\log V)\)。
整个思路过程应该是这样的:无法运用 sg 函数,寻找结论,发现势能量,全身心关注势能量,谁能改变势能量?gcd,这跟 gcd 是多少有关,gcd 为偶数时才行。gcd 的奇偶性只和全局有无奇数相关。接下来,能够感受出两个人对局面的掌控能力很强(一般来说都是这样的,因为纯粹的愚蠢导致势能量变化是不可能发生的。只不过做题者本人不如题面里的玩家聪明,才容易产生控制力不足,可能性过多的错觉),至少对于全局有无奇数有相当的掌控。那就是他们在“选择”是否改变势能量的奇偶性,这种做法什么时候对他们有好处(一般来说,某个关键量如果在两人决策过程中有所改变,那一定是他们自主选择的结果,这就需要讨论,是谁想让关键量改变?关键量改变对谁有好处)?处于先天劣势的时候。
T-142 QOJ8546 26-3-25 B+
串起来了,都串起来了。信息的性质,我们在 T-102 稍微介绍过。其实,它和代数结构紧密地结合在一起,如下。
一个代数结构是一个集合,连同定义在该集合上的若干运算,这些运算满足特定的公理。例如对于集合 \(R\) 内的元素,可以定义若干双目运算“加法”“乘法”等等。一般来说,这个“集合”可能有两种现实意义,分别是:“集合”由你所维护的信息组成;“集合”由某种操作本身组成。
1.1 半群
定义:满足结合律的运算和对应元素 \((a+b)+c=a+(b+c)\)。还有封闭性要求运算结果仍然在集合内。
意义:可加性/可合并性。如果集合定义在信息上,那么可以按任意先后顺序合并信息,从而允许批合并一个连续段,或者应用分治数据结构,解决单答案问题等。如果集合定义在操作上,那么运算相当于操作的复合,就允许批合并操作,并把它们当作一个操作来处理,非常实用。
1.1.1 幺半群
定义:半群基础上,存在单位元 \(e\) 满足 \(e+a=a\)。
意义:允许信息与“空信息”合并,从而可以放心在线段树等中,构建“空节点”。我们见到的题目里,只要代数结构是半群,一般就也是幺半群。如果不是,不妨额外引入一个单位元,就能解决问题。
1.1.2 幂等半群/带
定义:半群基础上,保证幂等性 \(a+a=a\)。
意义:定义在信息上,就具备可重算性,允许重复合并,也就允许了更加野蛮的批合并求解单答案。例如 st 表。
1.1.2.1 交换幂等半群/半格
定义:幂等半群基础上,满足交换律 \(a+b=b+a\)。
意义:定义在集合上的交/并;定义在实数上的 max/min;gcd/lcm,就属于这样的代数结构。这种集合是天然的偏序集(集合内具备若干形如 \(a\le b\) 的关系,这个关系必须具备传递性。但是可以有若干对元素不可比较):若 \(a+b=a\) 则认为 \(a\le b\),那么 \(a\le b,b\le c\to a+c=(a+b)+c=a+b+b+c=(a+b)+(b+c)=a+b=a\to a\le c\)。这类代数结构是容斥的基础,见 T-101-3。也是 FWT 的背景,话说你有没有觉得与/或 FMT 特别像一个容斥?从而,我们可以类比着发明“快速 gcd/lcm 卷积”等。当然,我们无需发明“快速 max/min 卷积”(笑)。
为什么传递性证明没有用到交换律,但是要在满足交换律的代数结构上定义偏序集呢?因为交换律的作用是让左偏序和右偏序一致(\(a\le b\to b\ge a\)),从而得到一个自然的、对称的偏序关系,这也是算法中最常见的情形。这个不必纠结。
1.1.3 交换半群
定义:半群基础上,满足交换律。
意义:交换律使得合并时,不必按左右顺序。定义在操作上时,交换律是莫队的基础。
1.2 群
定义:幺半群基础上,每个元素有它对应的逆元,满足 \(b+b^{-1}=e\)。
意义:如果定义在信息上,是可减性,允许差分;如果定义在操作上,是可逆性,操作存在逆元,就允许撤销操作,用于莫队等算法。
1.2.1 循环群
定义:群内集合可以由生成元(用原根来理解)构造,集合 \(R=\{ng,n\in \mathbb{Z}\}\)。循环群可以通过“在一个环上转圈”来理解。
意义:例如取模意义下的指数运算。循环群要求 \(0g=e\)。有限循环群还要求存在正整数 \(x\) 使得 \(xg=e\)(无限循环群可以视作环特别大以至于直线)。
接下来,是定义在同一集合上,且有两种运算的代数结构。
2.1 格
定义:两个定义集合一样的半格,设运算分别为 \(\cap,cup\)。这两种运算内部(自己和自己)具备交换律和结合律;两种运算之间存在吸收律 \(a\cup(a\cap b)=a,a\cap(a\cup b)=a\)。两种运算各自的幂等性可以由吸收律推出:\(a=a\cup (a\cap (a\cup a))==a\cup a\),另一个亦然。
意义:格意味着,对应偏序集的偏序 dag 满足,任意两个元素具备唯一“最近公共祖先”和唯一“最近公共子孙”,这两个元素分别是 \(a\cup b,a\cap b\) 的运算结果。集合交/并,max/min,gcd/lcm 就是格。
2.1.1 全序对合格
定义:全序格(偏序 dag 是一条链)一定是分配格,两个半格定义的运算之间具备分配律。格配备了“对合反序映射”,类似负数。
意义:max/min 或者二元布尔代数更精确地属于此类格。“对合”提示了类似 \(-\max(-a,-b)=\min(a,b)\) 的性质能够成立。
2.2 非交换半环/分配幺半群
定义:两个定义集合一样的幺半群,设运算分别为加法和乘法,则乘法对加法满足分配律 \(a\times (b+c)=a\times b+a\times c\)。注意这里的乘法是半群里的,不一定有逆元、交换律。
意义:将“信息合并”与“操作”分别对应加法和乘法。那么“非交换半环”就是一个特别合适的,对线段树“打 tag”过程的刻画,分配律允许标记下传,而“打 tag”这一操作的结合律允许标记合并。幺半群是为了允许存在空 tag 和空信息。
把 T-132 中关于多个 tag 问题的讨论复制过来:多个 tag ,就意味着混合多种不同的操作,但是它们能够被一个元素(也就是 tag)表示,且 tag 之间能够进行乘法运算(只有结合律,一般不满足交换律),tag 对信息的乘法运算(或者说影响)满足分配律。
一般来说,tag 是固定顺序多元组 \((a,b,c,d,...)\)(这个 tag 的意义是:先给信息操作一,传入 \(a\) 为参数;再以 \(b\) 为参数进行二操作,等等),操作的先后顺序(操作一二三四分别是谁)需要你来确定,必须合适。举例来说,对于只有加乘两种操作的情况,把操作序列封装为先乘 \(a\) 再加 \(b\)。需要关心的就是,tag 之间的乘法操作具体是什么(如何合并 tag);以及 tag 如何对信息做上乘法(影响)。
一般来说,tag 还可能是经过特殊定义乘法的矩阵,这种情况下,信息也需要变成对应类型的矩阵。矩阵乘法在半环上定义,这解释了为什么很多 tag 合并规则可以统一为矩阵运算。
2.2.1 热带半环
定义:max/+ 或者 min/+ 的半环。
意义:可以定义 max/+ 矩阵乘法等,广泛用于 dp 转移,可得到矩阵快速幂算法。加法对 min/max 有分配律,所以有常见变形 \(t+\max(a,b)=\max(t+a,t+b)\)。注意热带半环无法处理三操作 min/+/-,或者 min/max/+,见 T-130。
本题有三个轴,位置和两个值域。
关注答案,先枚举 \(x=a_i\),不妨设 \(y=a_j,j\ge i\)。对于本题来说,代数结构显然建立在操作上,是 max/min 两种混合运算,这显然是幺半群,可以通过“固定顺序封装”的方式合并多个操作。换句话说,枚举 \(x=a_i\) 以及在 \(i\) 处的操作方式以后,就确定了 \(i\) 及以后的所有操作方式,从而 \(y=\max(p,\min(y',q))\),其中 \(p,q\) 只跟 \(i\) 和 \(i\) 处的操作方式有关,而 \(y'\) 是进行完 \(i-1\) 位置的操作后 \(y\) 的值。注意到刚才钦定了 \(j\ge i\),所以最终 \(y\) 只能有 \(p,q\) 两种取值。枚举最终取到了 \(p\) 还是 \(q\),例如取到 \(p\) 那么相当于(可能有)限制 \(y'<p\);反之相当于限制 \(y'>q\)。再结合我们刚才枚举的 \(i\) 处的操作方式,可知对 \(x'\) 也是两种限制取其一,问题成功转化为 \(O(n)\) 次询问“能不能分配 \(i-1\) 及以前的操作序列使得 \([x'<f]=r,[y'<g]=s\)”。至于这些组 \(f,g,r,s\) 的值,只跟上述 \(p,q\) 有关,扫描 \(a\) 数组的值域轴即容易线段树求出。
按照 \(r,s\) 分讨四类。如果对 \(r=s\) 那么不用管;反之不妨设要求 \(x'>f,y'<g\)。就是三个轴的问题,可以最外层从大到小扫描 \(f\) 所在轴,每次相当于把一个位置涂黑。\(x'>f\) 的要求相当于,在 \(i-1\) 及之前选择一个被涂黑的位置做 max 操作,然后从此往后直到 \(i-1\) 都必须选择 max,故贪心地为了满足 \(y'\) 的限制,我们一定选最后一个黑位置,并且在此之前都选择 min 操作。线段树容易维护出这种最优策略下 \(y'\) 的取值,从而解决问题。
也可以把“令 \(x\) 跟某个定值取 min/max”视作关于 \(x\) 的分段函数,那么问题就和这些分段函数的复合有关。这样,定义在操作上的代数结构的性质,就容易看出了。
T-143 QOJ1813 26-3-25 S
先分析二级结构。询问之间的关系匪浅,不妨对不同的 \(k\) 做一询问 \((i,j,k)\)。问完所有 \(n-2\) 遍以后,大致能知道 \(a_i,a_j\) 这两个值构成的集合 \(\{p,q\},p<q\)(无法区分谁是 \(a_i\) 谁是 \(a_j\)),以及所有 \(a_t\in(p,q)\) 这些值对应的位置,还能知道一个集合 \(A\) 和集合 \(B\) 分别表示小于 \(p\)、大于 \(q\) 的元素之位置集合。这只是“大致能”,需要严密分讨:
-
若只有一个值重复两次及以上,则意味着 \(p=1,2\)(是一或二),\(q=n-1,n\) 二者有一成立,而且是谁成立我们也容易知道。换句话说,举个例子我们知道 \(p=1,2\) 成立,设令交互库回答二的位置为 \(k\)。因为 \(B\) 集合内仍有数,随意问一手 \((k,i,B)\) 即可知道 \(a_i=p\) 的成立性。假设成立(若不成立则交换 \(i,j\)),那么 \(\{a_k,a_i\}=\{1,2\}\),做询问二 \((k,i)\) 即可分辨。
-
若没有两次以上的值,则 \(p=1,2\) 且 \(q=n-1,n\)。那么用两次询问二分辨出最边界的四个值谁是谁,问题已经结束了。
-
若这 \(n-2\) 次结果中,存在两个重复出现两次及以上的值,那么 \(p,q\) 分别等于这两个,而令交互库回答这个值的位置 \(k\),就属于对应的 \(A,B\)。我们还必须知道 \(i,j\) 谁是谁,只需问一次 \((A,i,B)\) 就知道 \(a_i=p\) 是否成立。
接下来只需考虑 1. 或 3.,目前只用了 \(n-1\) 次询问一。并且剩余的 \(A,B\) 集合个数,与剩余询问二次数相同。
对于 \(A\) 集合来说,我们知道一个恰好在它边界以外的元素 \(i\),从而只要询问 \((A_1,A_2,i)\) 就能返回 \(A_1,A_2\) 中较大者。不妨任意选定一个 \(f\in A\),然后不停枚举 \(k\) 来问 \((f,k,i)\),直到返回值有两个一样的,这时我们就了解 \(a_f\) 了。这个策略最坏是用两次解决一个位置的(把被解决的位置从 \(A\) 中删除)。另外,如果枚举 \(k\) 的过程中找不到返回值一样的,那意味着 \(f=1,2\),仿照讨论过的样子,用一次询问二分辨即可。故对于 \(A\) 集合,用了至多 \(2|A|\) 次询问一和一次询问二。
总计至多 \(2|A|+2|B|+n-1\) 次询问一,大约 \(O(3n)\) 实际非常地不到;用了两次询问二。我没写这个,但是应该通过不了吧。
感觉最初的 \(n-1\) 次可能不太必要,关键在于用了好多次询问只为找出两个集合 \(A,B\),这很不好。回顾一下,我们扫描 \(k\) 并不断询问 \((i,j,k)\)。还是老样子,一直问直到发现本次返回值和以前的返回值重复了(这可以看作一种变现思想,如果没有重复,我不问白不问,因为用一步询问就找到一个位置,非常地不亏。设两个返回当前值的位置分别为 \(f,g\),返回的值是 \(t\))。这个时候,我如果继续扫描并询问 \((i,j,k)\),那我就是沙比。为什么呢?我刚才说,如果一次询问的返回信息是跟以前重复的,那么这次询问的效率不高,想要尽量避免这种情况发生。现成的优化方案在那里摆着,譬如说 \(t=p\) 的情形,那么 \(a_f<p\) 必然成立,故把 \(i,j\) 改成 \(f,j\)(不妨假设 \(a_i=p\))必然减少重复的可能性。
具体来说,如果不清楚 \(p,q\) 中谁是 \(t\),只需问一手 \((f,g,i)\),看返回值和 \(t\) 的相对关系,如果变大了就意味着 \(q=t\),反之 \(p=t\),这种情况最多出现一次(称之为“可怕情况”;最多一次是因为如果我们至少知道一个值 \(t'\) 的位置,那么看 \(t',t\) 的关系就能分辨它是谁了)。例如 \(p=t\) 时,如果不清楚 \(a_i=p\) 是否成立,只需问 \((f,i,t')\) 即可(重要情况);如果没有 \(t'\),那用询问二分辨 \(i,j\)(如果 \(a_j=p\) 则将二者互换),这也最多发生一次。之后就可以快乐地令 \(i\gets f\) 了,且 \(a_i\) 的值已经被找出了。边界情况 \(1,2\) 和 \(n-1,n\) 又总计要用两次询问二。所以这是一个 \(2n\) 次询问一,三次询问二的做法,不能通过。
边界情况的询问二不能省去,尝试省去第一次用于判断 \(a_i<a_j\) 成立性的询问二。看看我们知道什么,我们知道这件事情不能拖,必须当时就处理了;这件事情只能用询问一处理;这件事情发生的时候知道 \(p\) 的值,知道 \(a_f,a_g\) 都比那个值小,还知道 \(a_i,a_j\) 中的最小值等于 \(p\),其它的一概不知。这个时候,询问才刚刚开始(只问了两次询问一)。当前两次询问打了水漂,将 \(i,j\) 替换成 \(f,i\),这回我们明确地知道 \(a_f<a_i\),从头再来一遍即可。
算复杂度:“可怕情况”额外算一次,“重要情况”或者“打水漂”最多额外两次。故所有边角料是三次。考虑整个过程,除了边角料以外,每个值被交互库输出几次。因为 \(1,n\) 必不被输出,而其他元素至多被输出两次,所以总计 \(2n-4\) 次。加上边角料是 \(2n-1\) 次询问一,能够通过。询问二,必然两次。
唯一难点在于“这个时候 ... 那我就是沙比”那一段。核心思路如下:有一种情况好,有一种情况坏。好情况比平均步数要求要好,所以碰到了就直接过;坏情况我们不希望碰到,它是无底洞。交互的过程中,源源不断有辅助信息出现,我们利用辅助信息,不断贪心选择“好情况”次数不劣的方案,升级原有方案,这是不做白不做的好事,故我们一定做。
本题也可以看作归纳构造。在已知某个 \(i<j\) 的基础上,如果 \((i,j,k)\) 回答与先前的不重复,就视为把 \(a_k\) 找出来,归纳掉了,问题减小了一的规模(是“有 \(n-1\) 个数未知,只知道某个 \(i<j\),请通过交互询问出所有元素,步数限制 \(n-1\)”的子问题),一步操作带走一个元素,不归纳白不归纳;如果有重复,依旧尝试把问题归纳成规模小一的问题,不过当然可以改变所谓“已知的 \(i<j\)”具体是哪一对嘛。
所以说,归纳的时候一定要明确“被归纳的状态”究竟是什么状态,用自然语言描述一下此状态试试;不做白不做的好事,我们一定要做。
T-145 QOJ12167 26-3-27 A
整个图连通,则答案是零。否则跟操作顺序无关,只需描述操作点位,再乘上阶乘即可。
模拟几个小样例,发现大概率只需用一次操作。不妨把已知变现,先把所有能用一次操作搞定的情况排除掉,再进一步思考。
因为还要计方案数,所以枚举操作的点 \(x\)。一次操作是删边加边的过程,不妨变换为先删边再加边,删边的过程相当于把 \(x\) 从整个图中删去,所在连通块分裂;加边的过程相当于把 \(x\) 未直接相连的点都与它连上,这意味着所有非“原所在连通块”的连通块,都和 \(x\) 连通了。关键在于“原所在连通块”,也就是删边分裂的那个块,能否也连通上。
删除一个点,关注连通性,没想法吗?建立圆方树。从而,问题转化为“圆方树上,圆点 \(x\) 的各个子树内,是否各自存在初始图中不与 \(x\) 连边的点”。这很容易处理,只需枚举 \(x\) 连的所有边,然后开桶计数等等。但是我们关心的不太是“若保证一次操作即可,怎么算方案数”,而是“什么情况一次操作即可”。取反面,如果一次操作不可,那意味着所有点都不满足上述条件。任取一个边界元素叶子,它必须向连通块内所有点连边。有点像 T-106 中做的那样,一旦这件事情成立,就意味着不存在距离该叶子圆点超过二的圆点,否则“圆方树就不是圆方树”了。换句话说该圆方树是一个菊花,更进一步地显然原图连通块是一个团。所以原图的每个连通块都是团。
当然还可以采用“广义的广义串并联图方法”,用这个方法给原连通块构造一个解 \(x\)。但因为要得到“没解的图形态”,需要防止真的找出了解。仍旧关注边界元素叶子(关注度数为一的边界元素),它不准是解,所以它向所有人连边。那么它不是解,可与其父亲合并起来,但它不会给自己的父亲带来任何贡献(如果它向某个点没有边,则还会有贡献),相当于把它直接删了。就这样肯定能把连通块删完,从而连通块是团。
那么考虑,操作两次能解决哪些情况。分讨一下:如果有超过三个团,选择的两个点来自不同团,必然成功;反之来自同一个,该团大小必须等于二,否则这两个点会和团内其它点不连通。如果只有两个团,手玩一下小样例,或者描述一下解的形态,就知道必须完整地反转一个团。
本题和 AGC076B 类似,都是先发现答案极小,然后从零,一,二开始逐步分析,这些步骤数所能处理的图具备哪些性质。于是只有不具备这些性质的图才值得考虑,这就是变现。当然,那道题目还有一个就是,因为操作有顺序,所以两步操作能够解决的问题,必然是用第一步操作把状态转化为“一步操作能够解决的某种状态”,这就归到子问题里面了。
T-149 ARC146E 26-3-28 B
计数题目,无非就是 dp,组合,容斥,生成函数。我们介绍过排列计数的几个基本方法:扫描位置轴,逐位确定元素值(不常见);扫描位置轴,逐位确定元素在前缀中的相对大小 \(i\),并将原前缀中(你引用的 \(f_{i-1}\) 表示的某个原前缀方案),相对大小大于等于 \(i\) 的元素都往上移动一格;扫描位置轴,先将第 \(i\) 个元素赋值成 \(i\),然后再将它和原前缀的某个元素交换(错排的递推做法);扫描值域轴,每次将等于 \(i\) 的元素填入,用状态维护已填入元素的连续段的一些信息。这又分两类,一类是在原序列上填数,未填的数视作负无穷(不常见);一类相当于维护所有小于等于 \(i\) 的元素构成的子序列,只不过特别地按照某种方式,将子序列划分成了若干连续段。
本题不是排列,是任意序列,但其基本方法仍能迁移。选择扫描值域轴的第二类方法。设状态 \(f_{i,j,0/1/2}\) 表示考虑小于等于 \(i\) 元素的子序列,当前有 \(j\) 对 \(i\) 相邻,且子序列两端点有几个是 \(i\) 的方案数。复杂度 \(O(nV)\)。无法直接优化,打表看 dp 有效值,你发现对于一个 \(i\),第二维实际上只有 \(O(1)\) 种可能,故 \(O(n)\) 做完了。
T-150 AGC045D 26-3-28 A
最优策略肯定是,不断沿着置换环跳跃,如果跳完了整个置换环,就任选一个未知节点操作。如果操作到自环,就输了;如果初始时存在未亮的自环,也输了。故一个排列的胜率,只取决于构成排列的若干置换环的情况 \((a_i,b_i)\) 表示第 \(i\) 个置换环(最小编号第 \(i\) 小的)里面有 \(a_i\) 个点,其中 \(b_i\) 个被点亮。
“任选一个未知节点”显然只能随机选取一个,已经最优。在期望里面,我们介绍过“随机选取未涂黑元素,然后将它和一些相关元素涂黑”等价于“随机一个排序,逐个操作,如果当前元素已经被涂黑就跳过”是完全等价的。再复习一下与本题无关的“算上述过程的,选取到未涂黑元素的期望次数”等价于“算每个元素被选取到的期望之和”等价于“选该元素之前,没有选过能涂黑本元素的元素”等价于“对应随机排列上,本元素在所有上述元素之前”。回到本题,选取未知排列,然后选取一种排序方式并逐个操作,联合方案数 \((n!)^2\) 种,请算联合方案数成功的期望。这很怪异呀,因为要把一个排列任意重排?那还不如别重排了直接逐个操作,答案不会变的。
换句话说不断沿着置换环跳跃,如果跳完了整个置换环,就选编号上的下一个未知节点操作。翻译单点限制,假设排列中第一个 \(p_i=i\) 的(亮灯)位置是 \(x\),则编号大于该位置的元素,其所在置换环最小元素必须小于 \(x\)。枚举 \(x\),然后可以按照最小编号从小到大插入置换环到已知部分,得到一个 dp 做法。改逐步转移,也就是一个元素一个元素转移。按照编号从小到大扫描,每次新建一个自环,或者把当前元素融合到原有环中,融合方案实际上是“所有原环的边数之和”种。注意未亮灯的不准新建自环了。但问题在于如何保证小于 \(x\) 的最终不是自环,这就跟 T-103 里面说的一样,复杂限制可以容斥,钦定某 \(i\) 个是自环,其它的是不是自环无所谓。因为环边数和环点数完全相同,所以枚举 \(x,i\) 后就得到 \(O(1)\) 的组合式,求和即可。
所以说大部分 dp 也是按某个轴扫描处理的。如果没有明显的轴,就按序列位置轴先试试。还有就是基环树(森林)的计数技巧,有三个。分别是:先钦定一些环,然后把环缩成点,并用 prufer 序列完成常规森林计数。第二个,像本题一样逐步添点,维护“由前 \(i\) 个点构成的虚基环树森林”形态,就像桂花树一题那样。第三个,给边定向,指向父亲,环上会有两种方向,最后除以二即可。从小到大加入点,加入一个点时要把它可达的点全部加入。也就是说扫描 \(i\) 的过程中,要么添加一个包含 \(i\) 且编号都小于等于 \(i\) 的环;要么添加一条以 \(i\) 为结尾且编号都小于等于 \(i\) 的链,这链一直接到已有环上/已有的树上;要么添加一个 ρ 形态结构;要么等待机会,什么都不做,让后面的点把 \(i\) 添进去。

浙公网安备 33010602011771号