AGC 做题合集 #6

书接上回,代码可以在此处查看,对于 VP 的题目,可以在这里看代码。

  1. AGC032C Three Circuits[1]
  2. (VP)AGC025C Interval Game[2]
  3. (VP 补题)AGC025D Choosing Points[3]
  4. (VP 补题)AGC025F Addition and Andition[4]
  5. AGC056C 01 Balanced[5]
  6. AGC043C Giant Graph[6]
  7. AGC024F Simple Subsequence Problem[7]
  8. AGC031C Differ by 1 Bit[8]
  9. (VP)AGC022C Remainder Game[9]
  10. (VP 补题) AGC022E Median Replace[10]

  1. 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 的。
    ↩︎
  2. 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 维护即可。 ↩︎

  3. 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\)↩︎

  4. 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)\) 的。 ↩︎

  5. 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\) 计算输出答案即可。 ↩︎

  6. 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}\) 的,直接枚举即可。 ↩︎

  7. 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|\) 然后转移。 ↩︎

  8. AGC031C Differ by 1 Bit

    \(0\) \(\sim\) \(2^n-1\) 排成一个排列 \(P\) 满足:

    1. \(P_1=A\)
    2. \(P_{2^n}=B\)
    3. \(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)\) 问题了。 ↩︎

  9. 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 即可。 ↩︎

  10. 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\) 个数即可。 ↩︎

posted @ 2022-07-08 22:38  Werner_Yin  阅读(95)  评论(1编辑  收藏  举报