AGC 做题合集 #6
书接上回,代码可以在此处查看,对于 VP 的题目,可以在这里看代码。
- AGC032C Three Circuits[1]
- (VP)AGC025C Interval Game[2]
- (VP 补题)AGC025D Choosing Points[3]
- (VP 补题)AGC025F Addition and Andition[4]
- AGC056C 01 Balanced[5]
- AGC043C Giant Graph[6]
- AGC024F Simple Subsequence Problem[7]
- AGC031C Differ by 1 Bit[8]
- (VP)AGC022C Remainder Game[9]
- (VP 补题) AGC022E Median Replace[10]
AGC032C Three Circuits
- 有一张 \(N\) 个点 \(M\) 条边的简单无向连通图。
- 请你判断能否将边分成三个集合,每个集合都是一个可以多次经过重复点的环。
- \(1 \leq N, M \leq 10^5\)。
给一个萎做法:
考虑直接构建欧拉回路,然后根据欧拉回路剖分出尽可能多的环,如果环数 \(< 3\) 直接寄了。
当然,欧拉回路会让环数更小,于是这个是萎的,但是我们发现不同的起点和遍历顺序
shuffle
几下,多跑几遍,然后就过了。
考虑正经做法:
-
首先,根据欧拉回路对于度数的要求,只要存在一个点的度数是奇数,那么直接寄了。
-
因为是联通图,如果存在一个点的都市 \(\ge 6\),那么直接是 OK 的。
-
接下来只有度数为 \(2,4\) 的情况:
- 如果全部度数都是 \(2\),就是一个大环了,直接寄了。
- 考虑度数为 \(4\) 的点的个数,如果只有 \(1\) 个,那么就是寄了;如果有 \(3\) 个,手玩可以发现无论如何都是 OK 的;对于两个点,我们可以考虑这个中间是不是连着一堆长长的链,如果是,就寄了;否则就是 OK 的。
AGC025C Interval Game
- 数轴上有 \(N\) 个闭区间,第 \(i\) 个闭区间为 \([L_i,R_i]\)。
- A 和 B 玩游戏,A 初始在原点 \(0\),每次 B 选择一个还未选过的区间,A 要走到任意一个属于该区间的点。最后 A 要回到 \(0\)。
- A 希望最小化自己走过的路程,B 希望最大化 A 走过的路程,在两者都采取最优策略的情况下,求 A 走过的路程。
- \(1\le N\le 10^5\),\(-10^5\le L_i<R_i\le 10^5\)。
手玩样例可以发现,每次我们的移动,一定是一次走到左端点最右的区间,接下来一次走到右端点最左的区间……如此往复交替进行(最多开始先后顺序不一样)。
于是可以枚举开始的操作方向,
set
维护即可。 ↩︎AGC025D Choosing Points
给定 \(n, D_1,D_2\) , 要求构造一个在 \(2n\times 2n\) 的网格中选出 \(n^2\) 个点的方案, 使得任意两点间的距离不为 \(\sqrt {D_1}\) 或 \(\sqrt {D_2}\).
\(n\leqslant 300, D\leqslant 2\times 10^5\)。
日!又是碰巧猜对了“一个距离就是二分图”的结论,结果卡在“两个点就不是二分图了该怎么办啊啊啊”上面😂不过这个题真的是万分熟悉又耳目一新!一度怀疑如果去年就做了这题,我 NOI 的 Day2 也不会是这个 💩 样子了。
首先,对于一个距离,我们将所有违反限制的点建立一个图,容易发现这个是一个二分图。
给几种证明,第一种就是我 VP 的时候猜的时候给出的证明(超级超级感性理解的猜测),图一乐呵:
首先,如果出现了奇环,比较平凡的情况是三个点构成了一个等边三角形,只要证明不存在这种三角形即可(猜的):
我们可以发现,我们几乎画不出来这种图形,如果画出,一定有一个格点直角三角形满足两个直角边的比例是 \(\tan 15^{\circ}\),这是无理数,因此不可能!
一种比较正经的证明:
考虑令 \(D = 4^tp\),其中 \(p \not\equiv 0 \pmod 4\),所有距离为 \(D\) 的点可以表示为 \((a 2^t, b 2^t)\),其中 \(a^2 + b^2 = p\)。
- 如果 \(p \equiv 3 \pmod 4\),不存在解,任意染色。
- 如果 \(p \equiv 2 \pmod 4\),那么 \(a, b\) 一个是奇数,一个是偶数,根据 \(x + y\) 奇偶染色。
- 如果 \(p \equiv 1 \pmod 4\),那么 \(a, b\) 都是奇数,直接根据 \(x\) 染色即可。
接着我就陷入了两个点是什么图的情况了……
其实可以将两个图分开,两个二分图,需要选出一个点集,满足这个点集在两个二分图上面都是独立集。我们可以在两个二分图上面分别染色,每个点在一个图上面有 \(2\) 中染色情况,两个图上就有 \(4\) 中情况,点数是 \(4n^2\) 的,根据鸽巢原理,\(4\) 个集合一定存在一个集合满足点数 \(\ge n^2\)。 ↩︎
AGC025F Addition and Andition
给定长度为 \(n\) 的二进制数 \(x\) 和长度为 \(m\) 的 \(y\) 对他们进行 \(k\) 次以下操作:
- 令\(z=x \vee y\),并将 \(x\) 和 \(y\) 加上 \(z\)。
求出 \(k\) 次操作后的 \(x\) 和 \(y\)。
这个题启示了我们要考虑每个 \(1\) 最后会怎么移动。
只有一对 \(1\) 才会移动,于是我们可以考虑维护每一对 \(1\) 的贡献,如果从低位到高位,这个会产生一堆影响,并且高位是不确定的,于是我们要考虑从高位到低位计算答案。
如果这里有一对 \(1\),每次操作,它们都会向前移动一格,如果前面都是 \(0\),这个不要管,如果存在 \(1\),那么可以就会和这个 \(1\) “撞上”,我们可以计算撞上的贡献,如果还是一对 \(1\),可以继续推进,因此可以直接使用单调栈维护 \(1\) 的位置即可,每次撞上,都会减少 \(1\) 的个数,于是复杂度就是 \(\mathcal O(n)\) 的。 ↩︎
AGC056C 01 Balanced
构造一个长度为 \(n\) 的 \(01\) 字符串,满足 \(m\) 个条件,第 \(i\) 个条件形如 \([l_i, r_i]\) 中 \(0\),\(1\) 个数相同。如有多解,输出字典序最小的。
\(n \le 10^6, r_i - l_i + 1 \equiv 0 \pmod 2\)。
直接差分约束,对于限制,\((l - 1, r, 0), (r, l - 1, 0)\),对于相邻的 \((i, i+ 1, 1), (i + 1, i , 1)\) 即可,然后发现全部是正边,显然有解。
最后根据跑出来的 \(dis\) 计算输出答案即可。 ↩︎
AGC043C Giant Graph
给定三个简单无向图 \(G_1,G_2,G_3\),其中每个图的点数均为 \(n\),边数分别为 \(m_1,m_2,m_3\)。
现在根据 \(G_1,G_2,G_3\) 构造一个新的无向图 \(G\)。\(G\) 有 \(n^3\) 个点,每个点可以表示为 \((x,y,z)\),对应 \(G_1\) 中的点 \(x\),\(G_2\) 中的点 \(y\),\(G_3\) 中的点 \(z\)。边集的构造方式如下:
- 若 \(G_1\) 中存在一条边 \((u,v)\),则对于任意 \(1\le a, b\le n\),在 \(G\) 中添加边 \(((u,a,b),(v,a,b))\);
- 若 \(G_2\) 中存在一条边 \((u,v)\),则对于任意 \(1\le a, b\le n\),在 \(G\) 中添加边 \(((a,u,b),(a,v,b))\);
- 若 \(G_3\) 中存在一条边 \((u,v)\),则对于任意 \(1\le a, b\le n\),在 \(G\) 中添加边 \(((a,b,u),(a,b,v))\).
对于 \(G\) 中的任意一个点 \((x,y,z)\),定义其点权为 \(10^{18(x+y+z)}\)。
试求 \(G\) 的最大权独立集的大小模 \(998244353\) 的值。
\(2\le n\le 10^5, 1\le m_1,m_2,m_3\le 10^5\)。
别看是个 C,但是难度到了 *2800,对着这题想了 \(\infty\) 年后,突然灵机一动就会了!
首先,权值的差异非常大,于是我们可以按照 \(x+y+z\) 的顺序选择每个点,如果一个点没有被 ban 掉,我们就直接选择,并且把它在这个 Giant 图上面相邻的点全部 ban 了。
想想这个过程类似于什么,考虑一个博弈游戏。
我们有三堆石头,对应三张图 \(G_1, G_2,G_3\),Alice 和 Bob 轮流操作,每个人操作的时候,可以选择 \(i \in [1, 3], a < b, (a, b) \in G_i\) 且第 \(i\) 堆石子的个数为 \(a\),然后让第 \(i\) 堆石子的个数变成 \(a\) 个,如果一个人不能操作了,那么就会输。
这个游戏的必输态就是我们最后选择的最大独立集,每次我们按照 \(x+y+z\) 选择点,如果一个点没有被 ban 就是必输态,然后把它的后继点全部设为必胜点。
这是 \(3\) 个博弈的游戏的组合问题,我们只要对于每个游戏,每张图求出其 \(\rm SG\) 函数,然后我们就要在三张图上面选择 \(i, j, k\),满足 \(\rm SG(1, i) \oplus SG(2, i) \oplus SG(3, i) = 0\),贡献就是 \(10^{18(i + j + k)}\),这个可以简单的使用 \(\rm FWT\) 解决。
PS:写完后瞟了一眼题解才发现傻了,实际上 \(\rm SG\) 函数不超过 \(\sqrt{m}\) 的,直接枚举即可。 ↩︎
AGC024F Simple Subsequence Problem
有一个
01
串集合 \(S\),其中每个串的长度都不超过 \(N\),你要求出至少是 \(S\) 中 \(K\) 个串的子序列的最长串,如果有多解,输出字典序最小的那组解。由于 \(S\) 可能很大,因此我们是这样描述 \(S\) 的:
- 你将得到 \((N+1)\) 个
01
串,第 \(i\) 个串的长度为 \(2^{i-1}\)。 - 第 \(i\) 个字符串的第 \(j\) 个字符,代表数字 \((j-1)\) 的、长度为 \((i-1)\) 的二进制表示是否出现在 \(S\) 中。
\(N \leq 20\)。
考虑如何判断一个串 \(A\) 是 \(B\) 的子序列,我们可以维护一个位置 \(pos\),然后枚举 \(A\) 的每一个位置 \(x\) ,找到 \(B\) 中 \(pos\) 后面第一个和 \(A[x]\) 相同的 \(pos'\),然后 \(pos \gets pos'\) 即可。
于是我们可以记录一个 DP,\(f(A|B)\) 表示目前已经进入子序列自动机完成匹配的部分是 \(A\),剩下待匹配串是 \(B\) 的方案数。
每次转移的时候,考虑让什么进入子序列自动机即可,然后将一大段删掉。
因为 \(A, B\) 的长度都是 \(20\) 级别,我们不能全部记录,于是可以直接记录 \(AB\) 合在一起的长度,已经 \(AB\) 合在一起的情况,每次枚举 \(|A|\) 然后转移。 ↩︎
- 你将得到 \((N+1)\) 个
AGC031C Differ by 1 Bit
将 \(0\) \(\sim\) \(2^n-1\) 排成一个排列 \(P\) 满足:
- \(P_1=A\)。
- \(P_{2^n}=B\)。
- \(P_i\) 与 \(P_{i+1}\) 在二进制表示下只相差 \(1\) 位。
若无满足条件的 \(P\),输出
NO
。否则第一行输出
YES
,第二行输出任意一个满足条件的序列。\(n \le 17\)。
首先,如果 \(A \oplus B\) 二进制下 \(1\) 个数是奇数一定有解。
至于构造,可以考虑递归构造,定义 \(\tt solve(n, A, B)\) 表示问题的解。
首先,我们假设问题是 \(\tt solve(n, 0, B)\),并且 \(B\) 第 \(n- 1\) 位为 \(1\)。我们可以类似于格雷码,递归构造 \(\tt solve(n - 1, 0, 1)\) 和 \(\tt solve(n - 1, 1, B')\),其中 \(B'\) 为 \(B\) 去掉第 \(n - 1\) 位的 \(1\) 的结果,将后者集体 \(\oplus\) \(2^{n - 1}\) 即可。
我们找到 \(B\) 的第一个为 \(1\) 的位置(一定存在),然后就是上面问题将答案中的 \(j\) 和 \(n - 1\) 位交换结果,于是正式解决了 \(\tt solve(n, 0, B)\)。
最后求出 \(\tt solve(n, 0, A \oplus B)\),将答案 \(\oplus A\) 即可,这个就是问题 \(\tt solve(n, A, B)\) 问题了。 ↩︎
AGC022C Remainder Game
给定一个序列 \(A\),希望通过若干次操作将其变为目标序列 \(B\)。
一次操作为选择一个正整数 \(k\),同时任意选择一些数 \(a_i\) 将它们变成原数 \(a_i\) 除以 \(k\) 的余数(相当于对每一个数任意选择变化或不变化),这次操作的代价为 \(2^k\)。
总代价为所有操作代价之和,求最小总代价。
如果无论如何也不能变成 \(B\) 序列,输出
-1
。\(n, a_i \le 50\)。
VP 的时候想其他奇奇怪怪的问题去了,导致 \(\infty\) 年才切……
不会吧,不会吧,有人第一眼想到的是 DP 吧……注意到代价差异比较大,于是直接从大到小贪心,能不选一个 \(k\) 就不选一个 \(k\)。
如果不选当前的 \(k\),那么我们就将之前的所有选的数和之后所有 \(<k\) 的数拿出来,\(\tt check\) 一下是否合法。
显然,直接建图 BFS 即可。 ↩︎
AGC022E Median Replace
有个奇数长度的 \(01\) 串 \(s\) 其中有若干位置是
?
。每次可将 \(3\) 个连续的字符替换成这三个数的中位数。
求有多少方案将 \(?\) 替换成 \(0/1\) 使得进行 \(\frac{N-1}{2}\) 次操作后的字符串是 \(1\)。
\(|s| \le 30000\)。
想到了用栈,但是感觉不行于是弃疗选择打表了🤣,自闭了……
考虑如何判定,我们维护一个栈,满足栈底到栈顶是一长段 \(1\) 然后是一长段 \(0\) 构成。
考虑加数:
-
加 \(0\):
- 栈顶是 \(0\):如果有两个,直接发动技能变成只有 \(1\) 个 \(0\),显然更利于后面的结果,否则直接加;
- 栈顶是 \(1\):直接加!
-
加 \(1\):
- 栈顶是 \(0\):\(01\) 抵消了,后面这 \(3\) 个数取决于之后的数,于是可以删除栈顶的 \(0\);
- 栈顶是 \(1\):如果有两个 \(1\),不加(已经比较优秀了,最后答案一定是 \(1\)),否则直接加。
最后只要满足 \(1\) 个数 \(\ge\) \(0\) 个数即可。
显然,栈中间的 \(01\) 个数不超过 \(2\),于是通过 DP 记录 \(01\) 个数即可。 ↩︎
-