Cry_For_theMoon  

1. LIS with Stack

difficulty 非常恐怖的题,但是远没有这么难。

考虑对于确定的序列 \(a_1,a_2,...,a_n\) 来说,如何判断 \(a\) 能否栈排序。

容易发现 \(a\) 可以栈排序的充要条件是不存在 “\(2-3-1\)” 型的子序列,即不存在三个位置 \(i\lt j\lt k\) 满足 \(a_k\lt a_i\lt a_j\)

如果我们从前往后地进行 dp,则很难维护所需要的内容。

联想到笛卡尔树,我们可以想到区间 dp:设 \(f(l,r,x,y)\)\([l,r]\) 这一段区间,最长的,每个数都在 \([x,y]\) 范围内的合法序列长度。

转移的时候,枚举最大值的位置,然后枚举左侧的最大值,即可推出右侧的最小值,因为 \(n\) 与值域同阶,所以复杂度可以视作 \(O(n^6)\)

P.S. 容易发现,容易优化到 \(O(n^5)\) 的复杂度;另外,本题的计数版本也是类似的做法。

记录

2. 棋局

这个题是怎么放进 NOIP T4 的...... 看完题就会做了,从昨天七点半搞到今天十点半。

首先一类边和二类边能走到的点是容易确定的,而如果只有三类边,在不考虑吃子的情况下,会被已有的棋子划分成若干个连通块。

我们每次加入一个棋子,就会把一些连通块断成若干个新的连通块;此时容易想到我们把整个问题倒着考虑,这样就变成了合并连通块;这是我去年在考场上也想到了的东西(后面就是去年考场上想不到的了)。

问题在于,有些位置,它可能被多种方式走到。

显然,一个位置不可能既能通过一类边走到,也能通过二类边走到;因此我们只需要处理这两类重复:能被一类和三类走到,能被二类和三类走到。

容易发现“一类和三类”是容易的,因为最多只有 \(4\) 个这样的点需要判断;难点在于“二类和三类”:以水平方向为例,你可以容易处理出当前水平方向,通过二类边能走到的范围,我们需要知道在这一行的这个范围内,有多少个点能被三类边走到,你只需要对每个连通块的每一行都去维护一个线段树,然后就变成了线段树区间查询,因为你发现对于一个大小为 \(a\) 的连通块,有意义的行不超过 \(a\) 个,所以你总共只维护不超过 \(n\times m\) 颗线段树,合并连通块的时候直接进行线段树合并即可。

现在考虑吃子,我们只要对于当前连通块,研究与其相邻的异色棋子数目即可。所以你也可以放进线段树:这样一个棋子最多会给 \(4\) 个连通块做贡献,此时的去重是容易的,因为即使是二类边,也最多共产生 \(4\) 个可能位置。

有一个小问题,会出现于合并的情况:比如一个棋子给 \(a,b\) 两个连通块做了贡献,那么你的合并 \(a,b\),在线段树合并的过程中,在这里就是 or 而不是 add,但是相同权值的棋子又可能不止一个:所以我们需要把棋子的权值重新标号:按照 \(lvl\) 为第一关键字,\(idx\) 为第二关键字重新排序,此时它的位置就是它的权值。不难发现,这样棋子权值两两不同,且 \(i\)\(j\) 的要求仍然是 \(col_i\neq col_j \land lv_i\ge lv_j\)

\(N=n\times m\),则时间复杂度理论上可以做到 \(O(N\log N)\),但是上面的实现中,在 dsu 里用 map 去维护了线段树的树根,合并的时候采用启发式合并的策略,仍然是 \(O(N\log^2 N)\) 的,所以需要一定卡常。(不过我听说现在 CCF 的机子速度快得恐怖)

记录

3. Increasing K Times

非排列也可以类似定义欧拉数,并容易在 \(O(n^2)\) 的时间内解决。

如果最后钦定了一些位置是小于号,我们会发现整个序列被划分成了若干个非空连续严格上升段。

\(f(i)\) 是把所有数划分进 \(i\) 个连续严格上升段的方案数,则 \(f(i)\) 容易 \(O(n^2)\) 计算:通过二项式反演得到 \(g(i)\) 表示把所有数划分进 \(i\) 个非空连续上升段的方案数。

这样就可以得到 \(F(i)\) 表示钦定了 \(i\) 个位置是小于号的方案数:再次二项式反演得到 \(G(i)\) 表示恰好 \(i\) 个位置是小于号的方案数。

时间复杂度 \(O(n^2)\)

记录

4. Min Diff Sum

考虑固定一个位置 \(x\),所有区间包含 \(x\) 的人会取 \(x\);所有 \(R\lt x\) 的人会取 \(R\),所有 \(L\gt x\) 的人会取 \(L\):然后就可以排序+双指针在 \(O(n\log n+w)\) 的时间内解决这个问题。

这个方法成立的核心思想其实是因为至少存在一个人取到他的边界,否则一定可以调整答案。所以枚举是哪个人取到边界,共有 \(2n\) 种情况,那么就变成了上面的“固定一个位置 \(x\),...”的问题。

所以不难看出实质上还可以进一步优化到 \(O(n\log n)\)

记录

5. Sets Scores

非常厉害的题,对我很有启示。

考虑这个相邻集合恰有一处不同极其难研究,如果我们确定了任意两个相邻集合,究竟哪一位不同,记作 \(a_1,a_2,...,a_{n-1}\),那么不难看出,只要确定了 \(S_1\),就随之确定了整个序列。

你会发现一个事情:当我们试图把每一个数的贡献拆开来考虑的时候,其实是行不通的:因为每一个数并不独立。但是当我们确定了 \(a\) 序列以后,你会发现,一个数的出现次数仅与初始的 \(S_1\) 有关:更具体的,如果 \(S_1\) 初始包含 \(x\),那么它就一定会出现 \(A_x\) 次;如果 \(S_1\) 初始不包含 \(x\),那么它就一定会出现 \(B_x\) 次。而且我们会注意到 \(A_x+B_x=n\) 恒成立,即使我们不确切知道 \(A,B\) 具体的值,这难以研究。

那么对于所有的 \(2^M\) 种情况,最后加起来就应该是 \(\prod_{i=1}^{M}(A_i+B_i)=N^M\),而这是确定了 \(a\) 序列之后的:我们发现 \(a\) 序列究竟是什么其实无所谓,我们只需要知道一共有 \(M^{N-1}\) 种序列即可,所以我们就得到了最终答案:\(N^{M}\times M^{N-1}\),单次时间复杂度 \(O(\log N+\log M)\)

这个题给了我们什么启示呢?我们知道,对于一个变化的情况的每个部分乘积求和,往往考虑把各项拆开来,这在我的 ABC 和 ARC 做题记录中都有涉及总结,但是有时,就算我们拆开了,依旧非常棘手:比如我们完全可以设 \(A_{x,i}\) 表示 \(x\) 元素是否在第 \(i\) 个集合出现,那么答案应该是所有可能的 \(A\)\((A_{x,1}+A_{x,2}+....+A_{x,n})\) 的乘积,如果我们从每个因式拿出一项来,即对每个元素,钦定它在一个集合里必须出现,我们仍然会感到难以计数合法方案。所以这就陷入一个思路,表明我们上手就拆乘积是行不通的,因此我们必须重新推翻旧有的,套路化的想法:通过钦定了相邻集合的变化元,相当于把那个难以约束的条件直接强制满足了,然后研究此时的答案并发现了其良好的性质,从而得出了答案。

记录

6. Almost Perfect

考虑在置换环上研究这个问题,很快会得出结论:若 \(i\rightarrow j\rightarrow k\) 成立,那么 \(|i-k|\le 1\) 必须满足。这是合法的充要条件。

所以首先容易想到研究偶置换环,比如一个长度为 \(6\) 的环,我们研究第 \(1,3,5\) 个位置,如果第 \(1\) 个位置填 \(u\),第三个位置不妨设填了 \(u+1\),但是第五个位置呢?我们找不到合法的方案了:所以偶置换环大小不超过 \(4\)

类似地分析,可以发现:奇环大小不超过 \(1\)

另外,长度为 \(2\) 的偶环可以任意组合,长度为 \(4\) 的偶环是两个值相邻的对 \((u,u+1)\) 拼合而成的,且有两种方式。

因此枚举用来“拼”的二元“对”个数即可在 \(O(n)\) 时间内求得答案。

记录

7. 交通规划

观察部分分,我们来研究 \(k=2\) 的情况:若两点同色,则答案显然为 \(0\),否则我们可以建立网络流模型求解,发现所求即为最小割,因此建立原图对偶图,跑出源到汇的最短路即可拿到 \(k\le 2\)\(45\) 分。

\(k=2\) 的情况给了我们启示:对于 \(k\le 50\) 的情况,仍然可以建立网络流模型,结合 \(k=2\) 的部分分,我们发现已经能获得了 80 分!在赛场上,我们此时基本就会选择求稳收手了,收益是非常可观的(这让我想起 NOI2016 的一个 \(n^2\) 暴力 \(95\) 分的题目)。

但是 \(k\ge 2\) 的时候,就不能再直接转成对偶图最短路了:但我们仍然可以建出平面图的对偶图。我们意识到,网络流的想法走入了死路;如果想要进一步突破,方法就是从 \(k=2\) 时的对偶图最短路做法进一步深入。

\(k=2\) 的时候,最外层的无穷大平面被两条有意义的射线分成了两部分分别代表我们的 \(S-T\),在对偶图上这两点的最短路,其实就把整个图劈成了两半,换言之把两个异色点分隔了。

\(k\gt 2\) 的时候,我们任意取出一对异色点,这两个点之间也必须被分隔开:分隔的方法只有一种:就是我们提到的,直接选一条路径把图劈开,只要两个点在两侧就行,但这仅是 \(k=2\) 的情况。事实上,你注意到我们只会分隔异色的节点,所以完全可以把相邻的同色节点合并,然后顺时针一圈下来,颜色就会是 \(0-1-0-1-...-0-1-(0)\) 的形态,考虑每两个相邻(显然是异色)点所夹的无穷大平面,它在对偶图里被所缩成了一个点 \(u\),若我们最后不从 \(u\) 往外找一条路径,那么这个平面两侧的两个异色点就不可能被分隔开,所以每个这样性质的点,都要去寻找另外一个点去匹配;另一方面,我们将看到,只要每个点都有匹配到,一定会把所有的异色点分隔开!这是因为由于两点异色,中间就间隔了奇数个“平面点”(指对偶图里把平面缩成的点),所以如果把平面点两两匹配,至少这内部有一个点会和外部的点连边,这样就把两个异色点分隔了!

所以现在的问题变成了: \(k\) 个点(新的 \(k\) 一定是偶数)需要进行两两匹配,已知两两匹配代价,求最小匹配。

此时我们会发现一些问题:如果两条选择的路径有交集,那就会重复把交集部分算两边。

事实上两条路径的边集是不应该有交集的,假设 \(u-v\)\(x-y\) 的路径有交集,首先根据最短路的性质,它们的交集一定是连续的一段,然后我们将看到直接连 \(u-x\)\(v-y\) 是严格更优秀的。

所以我们的问题其实不是问题,但是我们依旧不太会求最小匹配:最大匹配我们当然会求,难道这里还要一个最小费用最大流?那么我们还不如重新写一个最大流的算法呢。

注意到两条路径的边集不交:如果我们把这个东西近似地抽象成一个圆,然后依旧顺时针排布所有点,如果最后匹配 \(u-v\),就连这条弦,那么我们将会看到没有相交的弦。

因此断环成链后直接区间 dp 即可,单次复杂度 \(O(k^3+knm\log (nm))\),可以通过此题。

记录

8. 射命丸文的笔记

考虑首先对所有图的所有哈密尔顿回路求和,然后求出强连通竞赛图个数即可。

对于第一个问题,直接枚举哈密尔顿回路是什么即可,容易发现有 \((n-1)!\times 2^{\dbinom{n}{2}-n}\) 种方案。

对于第二个问题,考虑容斥,这里需要知道,竞赛图缩点以后一定形如一条链,枚举链首大小即可得到 \(f(n)=2^{\dbinom{n}{2}}-\sum_{i=1}^{n-1}\dbinom{n}{i}f(i)2^{\dbinom{n-i}{2}}\),分治 NTT 即可。

时间复杂度 \(O(n\log^2 n)\)

记录

9. Prefix Function Queries

这个题普及了一个叫做 KMP 自动机的科技。

考虑设 \(nxt(i,j)\) 表示前 \(i\) 个字符,往后加了一个字符 \(j\) 以后的 border 长度。

首先我们通过维护 fail,可以得到原串前 \(i\) 个字符的最长 border,然后不难发现 \(nxt(i,j)=nxt(fail,j)\) 成立;另外,特殊地,有 \(nxt(i,S[i+1])=i\)

容易发现 KMP 自动机的核心思想和 AC 自动机很相似,但优点是它可以支持在线的末端插入单个字符以及回滚,而 AC 自动机往往需要预先建好 trie 树,更倾向于离线。

不难看出时间复杂度是 \(O(26\times (\sum |S|+\sum |T|))\) 的。

事实上,利用 border 是 \(O(\log n)\) 个等差数列的事实,我们可以实现一个单次 \(O(\log n)\) 求 nxt 的方法:

考虑已知 \(nxt_{1\sim i-1}\),现在来求 \(nxt_i\)

初始设 \(S=s_{1\sim i-1}\),首先我们用 \(S\) 的最长 border 去尝试匹配;如果无法匹配,设这个 border 长度为 \(j\),显然 \(S\) 有长度为 \(i-1-j\) 的周期:所以下一次可以直接让长度为 \(j\bmod (i-1-j)\) 的 border 来尝试匹配,这等价于跳掉了一个等差数列。

记录

记录2

10. 论战捆竹竿

应该是给广大选手普及了两个当时的科技?

注意到任意时刻我们能往后接的内容的可选范围都是不会变的:设 \(S\) 有一个长度为 \(k\ge 0\) 的 border,那么你就可以接上一个 \(n-k\) 大小的串,这个串具体是什么也不重要,因为它既不会对我们后续的操作产生影响,而且我们还仅关注可能的长度数目。

所以可以抽象成这样一个问题:给出 \(m\le n\) 个正整数 \(a_1,a_2,...,a_m\),问多少个 \(B\le w-n\) 满足 \(\sum_{i=1}^{m}a_ix_i = B\) 有非负整数解,这是经典的同余最短路问题,具体详见 墨墨的等式。但我们要知道,同余最短路解决这个问题,边数就已经是 \(O(m\times a_{min})\) 起步了,放在本题显然是行不通的:我们完全可以让最大 border 变得很小,这样意味着最小周期非常大,也就是说此时边数的上界基本是 \(O(n^2)\) 的。

但是我们需要知道,一个串的所有 border 构成的数列,并不是一个无规律的数列。事实上如果我们按照大小顺序列出,则可以把 border 序列划分成 \(O(\log n)\) 级别个等差数列形式的子序列。这个结论,如果没有预先的了解,是很难在场上发现或者观察到的。我们将在最后证明。

结合这个结论,我们首先思考:如果我们得到的 \(a\) 仅有一个等差数列构成,会发生什么。

一个公差为正的等差数列形如 \(x,x+d,...,x+l\times d\)。如果直接建图连边(在模 \(x\) 意义下的图),我们将会看到会在 \(f(a)\rightarrow f((a+x+kd)\bmod x)\) 这里连一条边权为 \(x+kd\) 的边(\(0\le k\le l)\)。我们知道 \(kd\bmod x\) 这个东西的循环节位数是 \(\frac{x}{\gcd(d,x)}\),不难发现会把 \(0\sim y-1\) 通过这样的连边划分成 \(\gcd(d,x)\)
个环,每个环是可以单独拿出来考虑的。

你可能会发现,事实上在这个时候只有 \(0\) 所在的环才是有用的,而且这里完全不是一个环的形式,因为 \(0\) 处的 \(dis\) 不可能被更新,你可以以 \(0\) 为链头断环,然后做一个简单的 单调队列 dp。那么,当我们回到 \(O(\log n)\) 个等差数列的情况的时候,这就不适用了。

那么单个环呢?刚才提到了,如果真的只有一个等差数列,那么我们可以把 \(0\) 所在的环从 \(0\) 开始断环:此时不难发现,从当前 dis 最小的位置断环后做 dp 就行了。

由于各个环是独立的,这就意味着我们处理完了一个等差数列的情况,时间复杂度 \(O(n)\)

回到 \(O(\log n)\) 个等差数列的情况,容易感觉到此时的复杂度应该是 \(O(n\log n)\) 级别的,我们发现,每次同余最短路模的余数会发生变化!这是我们以往同余最短路的练习里所没有见过的。

但是同余最短路其实也蕴含了一个无穷项,公差为原模数的等差数列!所以套用上面的方法,就容易实现模数转换后对应 dis 的转化,而且由于项数不存在限制,这次也不需要单调队列了。这样我们就做完了这个题。

时间复杂度 \(O(n\log n)\)

记录(被 UOJ 卡常了,Luogu 上 400ms 左右,懒狗不想卡了。)

P.S. 基础 border 理论(关于 border 序列是 \(O(\log n)\) 个等差数列的证明):

弱周期引理: 若 \(a+b\le n\)\(a,b\) 为两个周期,则 \(\gcd(a,b)\) 也是 \(S\) 的周期。

周期引理(在这里不重要):把条件替换成 \(a+b-\gcd(a,b)\le n\) 即可。

结论 \(1\):一个长度为 \(n\) 的串 \(S\),所有长度 \(\le \lfloor \frac{n}{2} \rfloor\) 的周期构成等差数列。

证明:由弱周期引理得这些周期的 \(\gcd\) 也应该是 \(S\) 的周期,不难发现它还应该是 \(S\) 的最小周期,设长度为 \(g\)

那么理论上 \(g,2g,3g,....,kg,...\) 都应该是周期,直到长度大于 \(n\) 了为止,那么所欲小于等于一半长度的周期应该是连续的一段,即构成等差数列。

那么,对应地,一个串长度 \(\ge \lceil \frac{n}{2} \rceil\) 的 border 就会构成等差数列。

结论 \(2\) ,一个串的 border 可以视作 \(O(\log n)\) 个等差数列。

证明:考虑长度最大的 border,所有其它的 border 都是它的 border,设其长度为 \(m\),由结论 \(1\) 我们排除了所有长度在 \(O(\lceil \frac{m}{2} \rceil)\) 以上的 border:递归这个过程,容易发现最多递归 \(O(\log n)\) 次,得证。

11. ≥ K

应该是较为简单的 ARC E 了,但是 hfy 9min AC 依旧令我震惊。

首先 \(\lt K\) 不好做,考虑 \(a_i\leftarrow 2\times a_i-K\),这样约束条件变为相邻两个数的和必须非负。

方便起见,我们认为相同值的 \(a\) 也是可区分的,最后我们可以容易的除以频率的阶乘来将答案变为相同的 \(a\) 不可区分的情况。

容易想到容斥,但我们会发现钦定某些相邻位置 \(\lt K\) 也不存在良好性质,所以排除容斥想法。

考虑把数分成正负来考虑:两个负数不会相邻,所以容易想到先确定正数位置,再把负数位置插空放进去。

又因为如果把负数数值从小往大排出来,那么能填的位置数目具有单调性,且是一个包含关系,有类似 \(\prod_{i=0}^{k}(p_i-i)\) 这样的东西在里面。

但是先确定正数再确定负数是困难的,不管怎么设计 dp,怎么算都行不通。

考虑最大的若干个负数以及所有绝对值大于等于它们的正数,先加入这些正数,形成若干个空,加入一个负数只能在一个空里加入,且会把这个空从可选范围内删除。加入完毕后,从原集合删除这些正数和负数,重复这个过程;加入正数和负数都可以简单地组合得出。

最后再处理末尾还剩下若干未用的正数,它们此时随便插空都是可行的。

记录

12. 城市规划

应该是所有学习 GF 的人都做过的典题了(雾)。

在这里列出一些基本的东西。

首先,\(\exp(F(x))=\sum_{i\ge 0}\frac{F^i(x)}{i!}\),这里是关于 \(F(x)\) 而不是 \(x\) ,然后去泰勒展开的。

\(\ln\) 就会相对复杂一些:最基础的当然是 \(\ln(1+F(x))=\sum_{i\ge 1}(-1)^{i-1}\frac{F^i(x)}{i}\),那么如果想要去掉 \((-1)^{i-1}\) 我们就会得到 \(-\ln(1-F(x))=\sum_{i\ge 1}\frac{F^i(x)}{i}\)

关于 exp 的组合意义我认为只要举一个例子就能让人影响深刻了:考虑排列与置换环之间的对应关系,显然排列数的 EGF 是 \(\sum_{i\ge 0}\frac{i!}{i!}x^i=\frac{1}{1-x}\),而单个置换环的 EGF 显然是 \(\sum_{i\ge 1}\frac{(i-1)!}{i!}x^i=-\ln(1-x)\)

所以对置换环的 EGF 做 exp 过后得到的就是排列的 EGF。

这样的关系可以类比到树与森林/连通图与一般图(比如本题就是逆过来的应用)上:更一般地,应该是从若干标号元素放入一个集合的方法数,exp 后得到若干标号元素构成一个集族的方法数。

记录

13. Random Student ID

不颓了!复健!

对于一个人研究答案。容易发现我们只关注 lcp,而且分为三类:

  • 如果另一个人是我们研究的人的前缀,那么另一个人一定在前面。

  • 如果我们研究的人是另一个人的后缀,那么我们一定在另一个人的前面。

  • 否则,有一半的概率,我们研究的人在后面。

根据期望线性性,只需要把这三部人的人数都求出来即可。那么我们只需要求前两类就够了:对于前缀关系,我们容易想到利用 trie 解决,然后就做完了。

时间复杂度 \(O(\sum |S|)\),空间复杂度 \(O(c\times \sum |S|)\)

记录

14. Taboo

题目的本质是分成最少的段,使得每段都不出现给出的 \(t\) 个串。

如果是判定性问题,考虑用 ACAM 解决。

然后我们发现这里存在一个贪心性质:最前面的段尽可能的长一定是最优秀的。

让最前面的段尽可能的长其实就在判定的过程中实现了。

时间复杂度依旧是 \(O(\sum |S|)\),空间复杂度 \(O(c\times \sum |S|)\)

记录

15. Reversible Cards 2

我怎么觉得这个 G 比上面的 Ex 难?

其实也没多难:设初始全部正面的时候,数字和为 \(S\),翻一张卡相当于选中一个物品,贡献为 \(b-a\)。然后变成了询问获得 \(k-S\) 的贡献最少需要选中多少个物品,这个形式非常像背包!

\(c_i=b_i-a_i\),容易发现 \(\sum |c|\le M\),经典结论是不同的 \(c\) 不超过 \(O(\sqrt M)\) 个,所以直接二进制分组优化多重背包即可。

时间复杂度 \(O(M\sqrt M\log M)\),注意到常数非常小,运行的很快!

记录

16. Antichain

真他妈是绝顶厉害题。

考虑设 \(f(u,x)\) 表示 \(u\) 子树内选 \(x\) 个点的合法方案数,发现 \(x\) 不超过 \(sz_u\) 所以容易想到启发式合并优化这个过程。

注意到合并 \(f\) 的实质是卷积;轻儿子可以全部分治 ntt 卷起来,但是你不能再把它和重儿子卷起来,这样是错误的。

过程实质上是这样:轻儿子全部卷起来,和重儿子卷起来,再把 \(f(u,1)\) 加上 \(1\)。我们意识到问题就在第二步。

这个时候就有一个套路存在:我们不能把重儿子的答案和轻儿子卷起来,但我们是直接继承了重儿子的信息的,而一条重链最底端的答案一定是个简单多项式,这里是 \((x+1)\),然后你每上去一层,实质上是把这个多项式乘了另一个多项式,然后把 \(x^1\) 项系数 \(+1\),设多项式是 \(F_1,F_2,...,F_k\),你注意到最后到达这条重链顶端的时候答案是:

\[(...((x+1)\times F_1+x)\times F_2+x...)\times F_k+x \]

\(F(i)=\prod_{i=1}^{k}F_i\),你发现答案实质上就是 \(x\times (\sum_{i=1}^{k}F(i))+F(1)\),最后再加个 \(x\) 上去:而这两个东西,在你求出所有的 \(F\) 以后,是很容易分治 NTT 维护的。

然后就做完了,时间复杂度 \(O(n\log^3 n)\),8s 的时限跑了 2s 不到,还是很宽松的。

我们总结一下就会发现这个套路只适用于你不关注 dp 在每个位置的值:因为它只能得到每条链顶端的答案。

另外,这里有一个结论:如果你分治 NTT 的时候是找带权中点,而不是暴力劈一半,那么时间复杂度仍然是 \(O(n\log^2 n)\) 的,(带权中点就是让两边乘起来的次数都较为接近一半)。Alpha 说似乎是和全局平衡二叉树之类的东西有关,但是我也不是很懂。

记录

17. Matching Reduction

感觉还是比较简单的 EDU F?

首先让最大匹配减少一,动态网络流,看上去就很恶心。

注意到最大匹配数目等价于最小点覆盖,即为总点数减去最大独立集。

所以我们每次只需要删除一个不在最大独立集的点即可!

这等价于初始求出最小点覆盖,然后每次删除一个最小点覆盖内的点。

我在 图论杂谈 这篇博客中已经提到了利用网络流求解二分图最大匹配,借以构造出最小点覆盖的方法。

这样这个问题就在 \(O(m\sqrt n)\) 的时间内解决了。

记录

18. Illumination

还是比较简单的 Edu G !

首先我们来想静态问题怎么做。这里一开始我被卡了半天才看到 \(m=16\),乐。

既然 \(m=16\) 就意味着支持 \(2^m\) 也就支持我们容斥的想法:我们发现钦定哪些点不被覆盖,其它点无所谓,然后方案数是容易计算的:一个灯笼的值应该小于离他最近的,被钦定不亮的点的距离。那么你钦定的若干个不亮的点就把所有灯笼分成了若干段,每一段的贡献是可以独立计算的。

然后你就发现单次可以 \(O(2^m\times m)\) 计算,可能需要 \(O(nm^2)\) 预处理两个钦定不亮的点所形成的中间段的贡献。

考虑加入一个灯笼,容易发现容斥系数的正负性不会改变,变的只是某些情况的方案数:暴力枚举加入的灯笼被夹在了钦定不亮的两个点 \(i,j\) 之间,可以设 \(f(i)\) 是从前 \(i\) 个点里钦定一些不亮(且第 \(i\) 个点必须钦定),所有情况的答案和(带上容斥系数);类似定义 \(g\),然后贡献就是 \(f(i)\times g(j)\times ways(i,j)\)

这样单次就 \(O(m^2)\) 做完了。

时间复杂度 \(O((n+q)m^2)\)

记录

19. Madoka and The Best University

如果上来就变形成 \(\frac{c\times \gcd(a,b)}{\gcd(a,b,c)}\) 那么就没救了:三元 gcd 往往是难以处理的。

考虑枚举 \(c\),然后你就知道了 \(a+b\) 的和,设为 \(m=n-c\)。然后 \(\gcd(a,b)=\gcd(a,m-a)=\gcd(a,m)\) 所以此时 \(\gcd(a,b)\) 一定是 \(m\) 的约束,不超过 \(\sqrt{n}\) 个。

枚举最大公约数 \(g\) 以后,则你要确定 \(A+B=\frac{m}{g}\)\(\gcd(A,B)=1\)\((A,B)\) 个数,经典结论是这样的对数有 \(\phi(\frac{m}{g})\) 个。

那么这个问题可以在 \(O(n\sqrt n)\) 的复杂度解决。

还能更优秀:从枚举约数转为枚举倍数:先枚举 \(\gcd\),然后枚举 \(A+B\)\(\gcd\) 的多少倍,就可以做到 \(O(n\log n)\)

记录

20. Madoka and The First Session

我觉得这个 F 比同场 D、E 都简单。

首先思考如果 \(s\) 全为 \(1\) 怎么做。

对于一个操作 \(u,v\),我们可以一开始让两个数都减去 \(1\),然后选择一个位置加上 \(2\)

通过若干次减 \(1\) 可以得到一个初始的 \(a\),则必须满足 \(\forall i,a_i\le b_i\)\(b_i-a_i\) 是偶数。

那么我们就知道了一个位置恰好要被加几次。

考虑建立一个类二分图的结构:左部是 \(m\) 个操作,右部是 \(n\) 个点。对于一个操作 \(u,v\),从对应的操作点向右部的 \((u,v)\) 各连一条边:\(S\) 到操作点的容量是 \(1\),点到 \(T\) 的容量是其恰好要被加的次数。对这张图跑最大流即可得到答案。

问题发生在有些 \(s\)\(0\) 的情况。

如果一个操作的两个位置都是 \(s=0\) 的话,那么可以忽略。

如果一个操作的两个位置都是 \(s=1\),那么依旧如上建图。

问题是,如果 \(s_u=1\)\(s_v=0\) 这种情况发生,实际上可以视作:你可以给 \(s_u\) 加一次操作,也可以不加。

按照这样建图的话,看上去我们直接从操作点只连一条到 \(u\) 的边即可?并不行:因为只有三类操作没有容量(代表加的操作给了 \(s=0\) 的那一个位置),而我们这样建图,完全有可能让二类操作出现无容量的情况!

从建图角度,我们是无法规避这种情况发生的。

考虑先把二类边加入,跑一次 dinic,此时我们就让所有二类边都有容量了(如果还是不能满足要求,显然是无解的)。

然后此时再加入三类边,在此基础上跑第二次 dinic,容易发现之前的流量不会被退掉,所以就解决了这个问题。

你发现其实这个建图和二分图匹配没有什么区别,所以跑 dinic 的复杂度是 \(O(m\sqrt n)\) 的。

记录

21. Burenka and Traditions (hard version)

上午刚刚智力正常了一回下午就继续降智了呜呜呜。

首先这个操作的代价长的很奇怪,我们发现我们实质上只有两种操作:长度要么是 \(1\),要么是 \(2\),且代价都为 \(1\)

然后发现长度为 \(1\) 的肯定不会和长度为 \(2\) 的重叠,长度为 \(2\) 的重叠肯定是连环扣着的形式。

而一个段能以连环扣着的形式去消除当且仅当这一个段的 xor 和为 \(0\)

每当我们找到这样一个段答案就会减去一。

所以最后问题变成了寻找最多个数的不重叠的 xor 和为 \(0\) 的子段。

时间复杂度 \(O(n\log n)\)

记录

22. add 1

我第一次独立做出来难度这么高的 Ex 啊,可惜比赛的时候变量重复定义没调出来又变成经典赛后过题了。

首先进行这样一步转化:初始你有一个计数器 \(v=\max a\),每次,等概率选择一个 \(a_i\),令 \(v\) 变为 \(\max\{v-1,a_i\}\),问 \(v\) 变为 \(0\) 的期望操作次数。

这种带有“回退”情况的题,一个套路是,直接正着 dp,这在我 7月杂题 中的 Bowcraft 中有所体现!

考虑 dp:设 \(f(i)\) 表示从初始的 \(v\) 第一次变成 \(i\) 的期望次数,则有转移:

\[f(i)=1+f(i+1)+\frac{1}{n}\sum_{j\in T}(f_{i}-f_{a_j}) \]

其中 \(T\) 是所有满足 \(a_j\gt i\)\(j\) 的集合。

我们发现 \(T\) 只会变动 \(O(n)\) 次,当 \(T\) 在一段连续区间不变化的时候,整个转移可以写成:

\[f(i)=A\times f(i+1)+B \]

的形式。这是一个经典的技巧:当 \(A\neq 1\) 的时候,有 \((f(i)+D)^n=A^{i-j}(f(j)+D)\) 成立,其中 \(D=\frac{B}{A-1}\)

时间复杂度 \(O(n\log n)\)

记录

23. Perfect Binary Tree

首先需要注意到不可能有 \(20\) 阶以上的完全二叉树存在,所以我们可以舍弃所有深度大于 \(20\) 的点。

然后朴素的想法是:考虑设 \(f(i,j,k)\)\(i\) 子树选出 \(j\) 阶二叉树且最大深度为 \(k\) 的方案。

我们发现这个东西极其难合并,所以换个做法。

当树的深度非常小的时候(设为 \(h\)),有一种计算 dp 的方式:一个一个点加入,每次加入一个点,不断暴力跳祖先去更新其 dp 值。

本题中使用上述方法,直接按照编号往上跳即可(而且还贴心地保证了 \(p_i\lt i\) 成立,所以你不断向上跳,跳到的点都是已经存在的)。

时间复杂度 \(O(n\times h)\)

记录

24. Almost Sorted

感觉这场可能 DEF 需要循环左移一下位置,D 感觉是 3200 评了 2200。

\(p_i\) 是数 \(i\) 出现的位置:则本质上是钦定一个合法排列,然后将每个 \(i\) 替换成 \(p_i\),使其逆序对最小。

注意到位置 \(i\) 放的数在 \([i-k,i+k]\) 之间,得到一个 \(O(n2^{2k})\) 状态数目的做法:设 \(f(i,mask)\) 是填完前 \(i\) 位且 \([i-k,i+k]\) 内的使用状况为 \(mask\) 的最小逆序对数目。

注意到设最小的未使用值是 \(v\),则我们只能填入 \([v,v+k]\) 范围内的一个数,而 \(v\) 的取值在 \([i-k,i]\) 之间:所以设 \(f(i,v,mask)\) 是填完前 \(i\) 位且最小未使用值是 \(v\)\([v,v+k]\) 的使用状况为 \(mask\) 的最小逆序对,这样状态数降为 \(O(k2^kn)\),总复杂度 \(O(k^22^kn)\)

记录

25. Permutation

考虑已经得到一个大三角形,加入一个点,有两种情况:

  • 位于大三角形内部,则加入点以后可以忽略它,还是只关注外部的大三角形。

  • 形成一个新的大三角形,忽略一个进入内部的点。

当然也有可能都不满足,则不能加入这个点。

称第二类点为关键点,我们发现设加入的关键点为 \(a_1,a_2,...,a_k\),则你可以在相邻的关键点中间塞入一些非关键点。

考虑设 \(dp(x,y,z,k)\) 是最外圈的大三角形由 \((x,y,z)\) 组成,且最后一个关键点的末尾余下 \(k\) 个非关键点。

转移的时候,枚举下一个关键点,枚举它和上一个关键点之间夹有多少个非关键点 \(k'\) 即可转移,复杂度 \(O(n^6)\)

注意到 \(x,y,z\) 强制令其 \(x\lt y\lt z\),又一定有 \(k'\le k\) 所以大约有 \(\frac{1}{12}\) 的常数,实测通过毫无压力。

这里有一个点是判断一个点是否在三角形内部,我没有计算几何水平所以选择了利用海伦公式爆算面积,EPS开到 \(10^{-3}\) 才能过 \((10^{-5}\) 就会判成面积不相等了...)。

记录

posted on 2022-09-03 16:46  Cry_For_theMoon  阅读(230)  评论(2编辑  收藏  举报