Loading

说的道理大战 AT 三百回合

板刷 AT 记录。太套路的题不会选。

简单题

AGC037D

关键词:网络流

\(D\) 中每一行的数字分为一组,\(C\) 中每一行中所有的数字必定在同一组;\(B\) 中每一列必定有每一组的数字刚好一个。
于是建出二分图,由第 \(i\) 行连向 \(A\) 这一行中每个数字所属的组,一个完美匹配对应 \(B\) 中一列的方案。左右部每个结点都恰好有 \(n\) 条边,一定可以找到 \(n\) 个不使用重复边的完美匹配。于是跑 \(m\) 次最大流就做完了。

待完成

好像还可以用 Vizing 定理做到更优的复杂度。暂时还不会。

AGC041D

关键词:dp

第三个条件中,\(S\) 一定是最大的,\(T\) 一定是最小的,发现只有 \(k\leq\lfloor\frac {n-1}2\rfloor\) 的限制是有用的;进一步地,\(k=\lfloor\frac {n-1}2\rfloor\) 的限制是最严的,只需要考虑它就行了。
套路性的,一开始先令所有数都等于 \(n\),每次可以选取一个前缀减 \(1\),同时要满足限制,相当于做一个背包。

AGC043D

关键词:找性质

首先,一个合法的排列中肯定没有一个数比紧跟在它后面的三个数都大,因为 \(P_i>P_{i+1}\) 只可能在 \(P_i\)\(P_{i+1}\)\(A\) 中的同一组时发生。
大胆猜想这是一个充要条件。但是这个条件并不充分。考虑它的本质,\(A\) 中的一组可以拆分为 \(P\) 中的若干极长段,每一段都满足段内的第一个数大于段内的其他数,\(A\) 中的一组也只能被这样的段组成。于是 \(P\) 是否合法能用长度为 \(1,2\) 的极长段的数量以及是否有长度大于 \(3\) 的段判定。
下面假设 \(P\) 中所有极长段的长度都不超过 \(3\)
当长度为 \(1\) 的极长段的数量大于等于长度为 \(2\) 的时,每个长度为 \(2\) 的段都可以与一个长度为 \(1\) 的段配对,剩下的长度为 \(1\) 的段之间任意配对,一定合法;否则最后会剩下一些长度为 \(2\) 的段无法配对,一定不合法。
计数部分。每次插入一个长度不超过 \(3\) 的段,记录长度为 \(1\) 的段数减去长度为 \(2\) 的段数(判断是否合法)。使用经典 trick,不考虑目前所有数的具体值,只考虑大小关系,一个段的开头比前面的所有数(上一段的开头)都大,只有一种选择,而不是段的开头的部分在不超过段首的前提下可以插入到任意数之间。

AGC045B

关键词:贪心,+1-1 前缀和

\(0\) 看作 \(-1\)\(1\) 看作 \(+1\),做前缀和,则答案等于最大值减去最小值。
考虑枚举最大值,最大化最小值,即能填 \(1\) 就填 \(1\),不能填就填 \(0\)
这样直接做是 \(O(n^2)\) 的,但是最大值每增加 \(2\),最小值最多也增加 \(2\),所以对于最小的最大值与最小的最大值 \(+1\) 分别做一遍就行了。

AGC045C

关键词:dp

先假设 \(A\geq B\),否则交换 \(A,B\)。一个合法的最终序列,最后几次操作必定是先使用 \(0\) 覆盖,再使用若干次 \(1\) 覆盖,由于 \(A\geq B\),所以 \(0\) 覆盖的部分的两边是可以自由选择的。
因此一个序列可以被得到当且仅当存在一段长度大于等于 \(A\) 的区间,区间中所有极长 \(1\) 连续段的长度都大于等于 \(B\)
设计 dp,对不合法的序列进行计数,设 \(f_{i,j}\) 表示做到 \(i\),满足上面条件的后缀长为 \(j\) 的序列数,每次转移填一个 \(1\) 连续段(可以为空)与一个 \(0\),根据 \(1\) 连续段的长度 \(k\) 是否小于 \(B\) 与是否为 \(0\)\(f_{i,j}\) 转移到 \(f_{i+k+1,j+k+1}\)\(f_{i+k+1,1}\)
可以前缀和优化,时间复杂度为 \(O(n^2)\)

AGC047C

关键词:多项式,数论,构造

这个式子一看就很卷积。但是因为求的是 \(\bmod P\) 的结果之和,而不是答案 \(\bmod P\),所以显然没法直接卷。
考虑从值域入手。把一个数表示成 \(g^b\bmod P\),则它在多项式中对应的下标为 \(b\),那么两个数相乘得到 \(g^{b+c}\bmod P\)(对应两个多项式卷在一起),由 \(b+c\) 倒推出对应值即可。
因为 \(P\) 是质数,所以 \(g\)\(P\) 的原根即可,不重不漏。特别注意,因为欧拉定理,所以卷完之后多项式下标 \(i\) 对应的其实是 \(g^{i\bmod (P-1)}\)

AGC050A

关键词:构造

奇妙构造题。首先,看到这个数据范围,容易想到次数可以描述为 \(\log n\)
考虑一个完全二叉树结构,相当于每次在 \(0\)\(1\) 两种二进制位中选一个并加入到原数的最低位后,但显然不能对于每个点都建这样一颗二叉树。
于是考虑这样的构造:由每个点 \(i\)\(2i,2i+1\) 连边,若 \(2i\)\(2i+1\) 超过 \(n\) 则改为连向 \(2i-n\)\(2i+1-n\)。这样相当于进行上面的过程,然后对 \(n\) 取模,每个数可以变成 \(2^{10}\) 个数,且这些数之间是相邻的,模 \(n\) 之后一定有一个数等于想要到达的数。

AGC050C

关键词:倒序考虑,拆限制到前缀

最优策略是显然的。S 尽量往目前可活动区间的中点走,B 放在 S 的旁边使 S 的可活动区间最小。
不难发现,B 在放 \(O(\log n)\) 次后必胜。这启发我们将 S 的获胜条件拆成 \(\log\) 个几乎独立的限制,两个限制之间仅与位置有关。
从最后一次放障碍往前倒推,S 必胜当且仅当倒数第 \(i+1\) 次放障碍到倒数第 \(i\) 次放之间 S 至少能走 \(s^{i-1}\) 步,于是容易设计 dp,时间复杂度为 \(O(n\log n)\)

中等题

AGC017F

关键词:轮廓线 dp

如果直接记录当前的折线和上一条折线,复杂度肯定爆炸了。考虑轮廓线 dp,进行状压,\(0,1\) 分别表示轮廓线往左/右走。
\(f_{i,j,k}\) 表示目前在放第 \(i\) 条线,走到第 \(j\) 行(从第 \(0\) 行出发),目前的轮廓线为 \(k\),其中 \(k\) 的前 \(j\) 位表示第 \(i\) 条线目前已经放上的部分,后 \(n-j-1\) 位表示无视第二种限制后第 \(i\) 条线剩余部分字典序最小的方案,这样就不需要记录第 \(i-1\) 条线目前走到哪了。
如果第 \(i\) 条线向左走,显然是顶到边界的,或者向右走并且顶到边界,轮廓线不变;如果向右走且轮廓线向左走,则轮廓线在下一个往右走的位置会变成往左走,剩余的位置走法不变,直接转移即可。时间复杂度 \(O(2^nnm)\)

AGC024F

关键词:高维前缀和、自动机

如果直接每次删掉序列的一个元素,肯定会算重。考虑把过程搬到子序列自动机上,在子序列中插入一个元素时找到原序列中第一个该元素的位置,将这个位置及以前的部分删掉,这样子序列与原序列在任意时刻的长度之和小于等于 \(n\),且不会算重。这个过程也可以理解为高维前缀和一位一位操作。时间复杂度 \(O(2^nn)\)

AGC035C

关键词:构造

发现有优秀性质,当 \(x\) 为偶数时,\(x\oplus 1=x+1\),于是连边 \(1→x→n+x+1,1→x+1→n+x\)。对于 \(1\) 要特殊处理,在任意一个 \(n+x\) 后再接上 \(n+1\) 即可。
如果 \(n\) 为偶数,则找不到权值为 \(n+1\) 的点,因此找到 \(x\oplus y\oplus 1=n\)\(x\)\(y\),连接 \(x→n,y→2n\)。当 \(n=2^x\) 时找不到这样的 \(x,y\),此时使用其他任何数都异或不出 \(n\),显然无解;否则取 \(x=2^{\lfloor\log_2n\rfloor}\) 即可,\(y\) 一定小于 \(n\)

AGC035D

关键词:区间 dp

考虑计算每一个位置对最终答案的贡献,先去除 \(a_1\)\(a_n\) 两个位置。
对于一个区间 \([l,r]\),钦定该区间内最后删掉的那个位置 \(i\)。区间内在 \(i\) 左边最后删掉的数会分别对左边界外的部分和 \(i\) 产生 \(1\) 份贡献,而 \(i\) 又会分别对左边界、右边界外的部分产生 \(1\) 份贡献;\(i\) 右边的部分类似。
于是设计状态 \(f_{l,r,x,y}\) 表示区间 \([l,r]\),区间中最后删掉的数每对左边界外的部分产生 \(1\) 的贡献就会对答案产生 \(x\) 的贡献,每对右边界外的部分产生 \(1\) 的贡献就会对答案产生 \(y\) 的贡献。
转移时枚举 \(i\),左边(即 \([l,i-1]\))最后删掉的数会对 \(l\) 左侧的部分产生 \(x\) 的贡献,对 \(i\)(即右侧的部分)产生 \(x+y\) 的贡献,因此 \(f_{l,r,x,y}=\min\limits_{i=l}^{r}\{f_{l,i-1,x,x+y}+f_{i+1,r,x+y,x}+(x+y)a_i\}\)。初始状态为 \(f_{1,n,1,1}\)
分析一下时间复杂度。一个状态对应一段长度小于等于 \(n\) 减去区间长度的 01 序列,0 表示 \(x=x+y\)1 表示 \(y=x+y\)。对于长度为 \(i\) 的区间的所有状态,一个长为 \(j\)01 序列可以对应 \(n-i-j+1\) 个区间,设 \(F(x)=\sum_{i=1}^{x}2^{x-i}i\),则状态数为 \(O(F(n-i))\)。设

\[G(x)=\sum_{i=1}^{x}\frac{i}{2^i}\leq\sum_{i=1}^{x}\frac{2^{\lceil\log_2i\rceil}}{2^i}=O(\sum_{i=1}^{x}\frac{1}{2^i})=O(1), \]

\(F(x)=2^xG(x)=O(2^x)\),状态总数为 \(O(\sum_{i=1}^{n}2^{i})=O(2^n)\);转移数为 \(O(\sum_{i=1}^{n}2^{n-i}i)\),按照上面的分析也是 \(O(2^n)\) 的。需要记忆化搜索保证复杂度。

AGC036D

关键词:差分约束

这个图可以看做一个差分约束模型,记到每个点的最短路为 \(a_i\),有 \(a_i\geq a_{i+1}\)。进行差分,记 \(b_i=a_i-a{i+1}\)
每一条 \(i<j\) 的额外限制相当于 \(\sum\limits_{k=i}^{j-1}b_i\geq1\),每一条 \(i>j\) 的额外限制相当于 \(\sum\limits_{k=j}^{i-1}b_i\leq1\),显然最优情况下 \(b_i\) 只能取 \(0/1\)。设 \(f_{i,j}\) 表示做到 \(i\),目前 \(b\) 中最后两个 \(1\) 的下标分别为 \(i\)\(j\),二维前缀和预处理一下,时间复杂度为 \(O(n^3)\)

AGC036E

关键词:贪心

首先,合并所有相邻的相同字符。假设三种字符按数量从小到大排序依次为 ABC,字符串被 A 分割为若干段。
答案显然有上界 \(num_a\times3\)。考虑在什么时候可以到达这个上界。当 BC 的数量相同时,可以每次删除一对 BCCB,在最劣情况下字符串会变成 ABCABCABC...,符合要求,因此可以到达上界。
BC 的数量不同时,每个段如果两侧是 C 并且存在 B 就将两侧的 C 删掉,直到 BC 的数量相同。如果仍然没有 C 可删,那只能删 ACCA 了。

AGC037F

关键词:没有

考虑对一个序列怎么操作。每次对于最小的数 \(x\) 的连续段,若长度小于 \(L\) 则不是合法序列,否则合并成 \(\lfloor\frac{长度}{L}\rfloor\)\(x+1\),若最终只剩余一种数且长度大于等于 \(L\) 或一开始就只有一个数则合法。
在原序列中选出一段子串同时进行上面的操作,该子串始终是原序列的子串。从小到大考虑所有数 \(x\),取出所有包含 \(x\) 的极长连续段,对于所有 \(i\),预处理出该连续段对应的原序列子串中合并出 \(i\)\(x+1\) 的前缀个数与后缀个数,以及该连续段合并出几个 \(x+1\);这样就可以线性地合并一个只包含 \(x\)\(x+1\) 的连续段(指把 \(x\) 合并成 \(x+1\))。
一个位置每次被合并贡献除以 \(L\),因此时间复杂度为 \(O(n\log n)\)

AGC040C

关键词:奇数位翻转,容斥

对01串的相邻同项操作时可以对奇数位取反。
进行如上变换,变成每次不能删去 AABB。于是问题变为 AB 的数量均不超过 \(\frac n2\) 的序列计数。
进行容斥。先假设超过 \(\frac n2\) 个的是 A,容易计算。然后乘 \(2\) 就可以了。特别牛逼。

AGC041E

关键词:构造,bitset

第一问。
考虑倒着做。在从右到左枚举平衡器的时候,维护 \(to_i\) 表示目前 \(i\) 号导线最终可以到达的导线的集合。感性理解一下,如果所有的导线都存在一种方案使它到达同一条导线,那么一定存在一种方案使所有的导线到达这一条导线。
这个东西可以用 bitset 维护,遇到一个平衡器时把两个端点的 bitset 或一下。判断是否有解与构造方案是容易的。

第二问。比较奇妙的构造。
\(m-1\) 个平衡器的方案先任意选取,设从左到右第一个平衡器连接的两条导线为 \(a\)\(b\),在不考虑这个平衡器的情况下最终有 \(x\) 个令牌到达导线 \(a\) 最终到达的那条导线,\(y\) 个令牌到达导线 \(b\) 最终到达的那条导线。
\(a\)\(b\) 最终到达的导线不同,则 \(x+y\leq n\)。若 \(x+1<n\),则第一个平衡器的方向设定为从 \(b\)\(a\) 一定是不稳定的;若 \(y+1<n\) 情况类似。因此在 \(2(n-1)>n\)\(n\geq 3\) 时一定有解。
\(a\)\(b\) 最终到达的导线相同,若 \(x≠n\),则随便连,否则考虑拓展上面的过程,以避免在某一个平衡器处出现了所有令牌到达同一条导线的情况。具体地,还是倒着扫,把每一个平衡器当成第一个平衡器按上面的方法做就行了。
这样有解的条件还是一样的(\(n\geq 3\))。发现 \(n=2\) 时一定无解。

AGC043C

关键词:博弈论

首先,最优方案肯定是不断贪心选 \(x+y+z\) 最大的那个。
给每条边定向,从编号小的点连向编号大的点,对于一个状态 \((x,y,z)\),若存在一张图,使得这个图中对应点的出边连向的所有状态(例如,三张图中分别存在 \(1→4,2→5,4→6\) 三条边,那么第一张图中 \((1,2,3)\) 连向的状态有 \((4,2,3)\),第二张图中 \((1,2,3)\) 连向的状态有 \((1,5,3)\),第三张图中 \((1,2,3)\) 没有连向的状态)都没有被选,则这个状态就会被选。
接下来是一步很妙的转化:将上面的过程转化为三个有向图游戏的和,若一个状态必败,那么这个状态会被选,否则不会被选。对于三张图中的每个结点都算出 SG 函数的值 \(A_i,B_i,C_i\),要求的就是 \(\sum\limits_{A_i\oplus B_j\oplus C_k=0}10^{18(i+j+k)}\)
这个东西可以用 FWT 求出来,但是 SG 函数的值是 \(O(\sqrt m)\) 的,所以可以枚举 \(A_i,B_j\),在对应的 \(C_k\) 查表,直接就是线性的。

AGC044C

关键词:trie

好题。
考虑把所有数都搞到一棵 trie 上。第一种操作直接打交换儿子标记即可。
第二种操作在常规的 trie 上很难做,但注意到所有进位操作本质上只有 \(n\) 种,于是从低位往高位建 trie,全局加 \(1\) 就相当于三颗子树轮换一下位置,然后递归进发生进位的那个子树中重复一样的过程。

AGC049D

关键词:背包,根号算法

先考虑只有右凸壳的情况。可以把凸性这个条件拆成一开始每个数都是 \(0\),若干次给一个后缀加上一条斜率为 \(1\) 的线段,最后再若干次全局加 \(1\)
这样就变成了一个完全背包问题,同时物品数是 \(O(\sqrt m)\) 的。全局加 \(1\) 的操作可以在预处理背包时解决。
如果有左凸壳,考虑把端点从左往右移动。不难发现,在移动过程中,会在左边依次加入 \(O(\sqrt m)\) 个物品(和上面的基本一样),同时在右边依次删去 \(O(\sqrt m)\) 个物品,时间复杂度为 \(O(m\sqrt m)\)。背包的删除过程其实就是 01 背包的过程中加上这个物品带来的的贡献变为减去这个物品带来的贡献,与 FMT 的还原部分类似。
为了防止算重,钦定端点是第一个斜率由负变为 \(0\) 的点,具体实现可以在最后统计答案时强行将 \(1\) 到端点这个前缀加上一条斜率为 \(-1\) 的线段。

AGC050D

关键词:记忆化搜索,概率期望,dp 状态设计

奇怪的状态设计。因为数据范围很小,所以可以考虑对于每个 \(i\) 分别做,这样就只需要考虑 \(i\) 前面、后面分别有几个人还没赢,以及游戏进行到第几轮(一轮定义为每个人都轮到一次),目前轮到还没赢的人中的第几个人,且只需要考虑 \(i\) 的获胜概率,转移方便。
设计状态 \(f_{a,b,c,d}\) 分别表示上面的条件分别为 \(a,b,c,d\)\(i\) 获胜的概率,转移时分类讨论目前轮到的人是在 \(i\) 的前面、后面还是 \(i\) 自己,枚举目前的人的输赢情况,可以 \(O(1)\) 转移。
这样是 \(O(n^5)\) 的。但是这个 dp 与 \(i\) 是无关的,因此可以使用记忆化搜索优化转移过程,做到 \(O(n^4)\)

AGC052B

关键词:差分与前缀和,构造

考虑将边权相同转化为从根到 \(i\) 路径上的边权异或和(接下来称为点权)相同。这样一次操作只会交换两个点的点权。
考虑有一个端点是根节点的情况。建一个虚拟结点,从虚拟结点往根连边即可。
最后判断原树与目标树的点权可重集是否相同。

难题

AGC039E

关键词:区间 dp

不可能有一个大区间套小区间,使得小区间与大区间不连通,因此考虑区间 dp。首先,套路性地,枚举 \(1\) 连的是哪一个点,破环为链。
考虑如何去刻画这个树的结构,使得可以分割为多个独立的子问题。可以强制区间中只有一个点往区间外连边,记录一个区间的左右端点,以及连向区间外的点。设目前考虑的子问题中左、右端点分别为 \(l,r\),连向区间外的点为 \(k\),记为 \((l,r,k)\)
为了保证连通,区间中必定有边跨过连接 \(k\) 的边,枚举这些边中端点最靠近区间两端的,设它的端点为 \(x,y\),分别枚举与 \(x,y\) 连通的最远点 \(i,j\),则可以划分出 \((l,i,x),(j,r,y),(i+1,j-1,k)\) 三个子问题。
不难发现,三个子问题互不连通,内部连通,这样计数一定是不重不漏的。这个做法是 \(O(n^7)\) 的,但是有很小的偏序常数,能过。
\((l,i,x),(j,r,y)\) 这两个子问题其实与 \(k\) 没有关系,枚举它们,预处理出所有 \(l,i,j,r\) 相同的子问题对的方案数之和,可以优化到 \(O(n^6)\)
此时枚举 \(l,r,k,i,j\) 转移的部分已经是 \(O(n^5)\) 的,考虑进一步优化上面预处理的部分。先枚举 \(l,i,x,y\),预处理出 \(x\) 可以连向 \(y\)\((l,i,x)\) 的答案之和,记为 \([l,i,y]\);然后枚举 \(l,i,j,k,y\),将 \([l,i,y]\)\((j,k,y)\) 乘起来,这样就将预处理部分也优化到了 \(O(n^5)\)

AGC040D

关键词:数学,二分

人类智慧题。首先把折线画出来(假设距离是横坐标,时间是纵坐标),要求的就是一个最大的 \(k\),使得 \(b\) 对应的折线往下平移且保持与 \(a\) 的折线有交点时,\(b\) 的折线与 \(x\) 轴的交点为 \((k,0)\)
想要两条折线有交点,最优策略是按照 \(a-b\) 排序;考虑由两条折线在 \(x\) 轴上方部分取 min 得到的折线,它的一个端点是固定的,要最大化另一个端点的 \(x\) 坐标,相当于最大化斜率,按照上面的策略排序后,每一段的斜率就是 \(\max(a_i,b_i)\)
\(\max(a_i,b_i)\) 排序,考虑枚举跨过 \(x\) 轴的那段对应的石板 \(k\),二分出一个最短的后缀,使得仅将这段后缀放在石板 \(k\) 后可以使两条折线有交点。
发现在 \(a_i-b_i<0\) 变为 \(a_i-b_i>0\) 时是交点最极限的位置,正好对应 \(\max(a,b)\),计算这段后缀的 \(\sum\max(a_i,b_i)\) 加上 \(b_k\),与全局的 \(\sum a_i\) 相比较,可以得出最优情况下 \(k\) 对应的线段是否有一部分在 \(x\) 轴以下(即是否可以与 \(x\) 轴相交)。于是判定部分也解决了。

AGC053C

关键词:概率期望,拆贡献,归纳证明

好题。
首先一定是把没有 \(2n\) 的那堆删光,设这堆为 \(A\),另一堆为 \(B\)。考虑一种牌堆的最优方案。
先有一种简单的情况:当前所有的 \(A_i\) 都满足它的下面都有一个小于它的 \(B_j\),此时存在策略,从上往下优先把 \(A_i<B_i\) 的给删掉,这样递归下去一定能在不删任何 \(B_i\) 的情况下删光 \(A\)
如果出现了一个 \(A_i\) 满足 \(\forall j\leq i,A_i>B_j\),那么考虑改进上面的过程,先去将最小的满足如上条件的 \(i\) 处不断删掉 \(B_i\) 使得 \(A_i<B_i\),不断重复这个过程,然后按上面的过程做就行了。这样显然不会让原先下面有一个小于它的 \(B_j\)\(i\) 的那个 \(B_j\) 无法找到。
于是记 \(d_i\) 表示第一个大于 \(A_i\)\(B_j\)\(j-i\) 的值,\(D\) 为所有 \(d_i\) 的最大值,答案为 \(n+d\)
答案显然可以拆成对于每个 \(x\),算 \(D\geq x\) 的牌堆数量,再次转化为算 \(D\leq x\) 的牌堆数量,记为 \(P(x)\),这个东西由 \(n\) 个条件 \(d_i\leq x\) 组成,设每个条件为 \(s_i\),可以拆成 \(\prod\limits_{i=1}^{n} P(s_i|s_1s_2\dots s_{i-1})\)
这个东西不太好算,但是可以算 \(s_1\)\(s_{i-1}\) 都成立的条件下 \(s_i\) 不成立的概率,需要满足 \(A_i\)\(B_1\)\(B_{\min(i+D,n)}\)(显然)与 \(A_1\)\(A_{i-1}\) 都大(否则 \(B_{j+D}\) 必满足 \(A_i<A_j<B_{j+D}\)),概率为 \(\frac{1}{i+\min(i+D,n)}\),然后就好算了。
实现上预处理奇偶阶乘即可。

posted @ 2025-01-09 11:58  AsiraeM  阅读(46)  评论(0)    收藏  举报