2023.3&4 做题记录
为什么是 3&4 呢,因为宇宙射线轰击比特翻转了(中间集训懒得更了,3月的太少干脆整个合集)。
3.1
[SCOI2008]天平
标签:差分约束
来源:差分约束杂题选做
第一眼看上去和差分约束完全扯不上联系,而且质量值域只有3非常疑惑,一开始想的是把每个砝码拆三个点跑可行解,但是不会建图。
这题是分别跑两个差分约束。
part one
设 \(mn_{i,j}\) 表示 \(i,j\) 两个砝码质量的差值 \(w_i-w_j\) 最少是多少(可以为负数)。
分一下类:
1 . \(i=j\) 或 \(a_{i,j}=\) =
,\(mn={i,j}=0\)
2 . \(a_{i,j}=\) +
,\(mn={i,j}=1\)
3 . \(a_{i,j}=\) -
,\(mn={i,j}=-2\)
4 . \(a_{i,j}=\) ?
,\(mn={i,j}=-2\)
这个差分约束是形如 \(w_i-w_j>=mn_{i,j}\),所以建图跑最长路。
因为本题的特殊性,需要跑全源最长路(每个点对都需要知道具体的值),而且有负权,图规模很小所以直接跑 floyd 即可。
part two
设 \(mx_{i,j}\) 表示 \(i,j\) 两个砝码质量的差值 \(w_i-w_j\) 最多是多少。
将上面的内容对偶过来即可,跑全源最短路。
这时候我们就求出来了任意两点的 \(mn\) 和 \(mx\),接下来考虑计数。
数据范围允许直接枚举 \(i,j\) \((i,j\neq A , i,j\neq B , i\neq j)\),依旧分类讨论,这里展开其中一类。
\(w_A+w_B>w_i+w_j\),转化为 \(w_A-w_i>w_j-w_B\) 或 \(w_A-w_j>w_i-w_B\),对应到求出的 \(mn\) 和 \(mx\) 上就是 \(mn_{A,i}>mx_{j,B}\) 或 \(mn_{A,j}>mx_{i,B}\)。
其他的情况是对称的,类似讨论。
总复杂度 \(O(n^3)\),足以通过。
3.4
[CTSC2008]祭祀
标签:二分图,Dilworth 定理
来源:与模拟赛的题用到的知识点相同的题
二分图综合题。
部分内容参考了兔队的博客,部分证明请移步,本文不详细展开。
简化题意为给出一张 DAG ,第一问求最长反链,第二问构造任意方案,第三问询问每个点是否能被选入最长反链。
Dilworth 定理的本身是定义在偏序集上的,在DAG中我们可以先传递闭包,把有向边看做偏序关系,所以 Dilworth 定理在传递闭包的DAG上适用。
于是可以转化为求出DAG的传递闭包后求最小不可重链覆盖,按套路可以转化为拆点二分图的最大匹配,第一问就解决了。
接下来考虑第二问,这里用逆推的方法。
有了最大匹配可以构造出最大独立集,具体的,可以先构造出最小点覆盖,最大独立集是最小点覆盖关于 \(|V|\) 的补集。
构造最小点覆盖是从某一部(假定为右部)的所有非匹配点出发,到另一部只能走非匹配边,回来只能走匹配边,所有遍历到的点组成的集合就是最小点覆盖。
正确性考虑Konig定理:最小点覆盖的点数等于最大匹配的边数。
首先最小点覆盖一定是大于等于最大匹配。左部的非匹配点一定不被遍历,右侧的非匹配点一定被遍历,因此每条匹配边的两端点恰好会被选一个,可以证明等于。
而选出最多的点构成独立集等价于去掉图中最少的点,使得剩下的点之间没有边,这个问题又等价于用最少的点覆盖所有的边,得证最大独立集是最小点覆盖的补集。
于是对每个右部非匹配点跑一遍上述流程,取所有的左侧未被遍历和右侧被遍历的就构成了最大独立集。
但是这只是二分图上的,还需要对应到DAG上,先给出结论:点属于最长反链的充要条件是这个点拆出的两个点都属于拆点二分图的最大独立集,设属于最长反链的集合是 \(A\),最大独立集是 \(I\),最大匹配是 \(S\),设 \(|S|=m\)。
证明考虑最大独立集的大小一定是 \(2n-m\),考虑 \(|I|-|A|\) 的含义是拆出的两个点不同时属于最大独立集的点,这样的点不可能超过 \(n\) 个,就有 \(|I|-|A|\leq n\),所以 \(|A|\geq n-m\)。
但是 \(|A|\leq n-m\),所以有 \(|A|=n-m\),以上得证,于是第二问就做完了。
第三问就很简单了,按套路计算删掉这个点是否对最长反链产生影响即可,不过这里删掉这个点是需要把所有与这个点产生偏序关系的点都删掉。
复杂度用 dinic 求最大匹配是 \(O(n(n^2-m)\sqrt n)\),足以通过。
[AGC028E] High Elements
标签:构造,贪心,DP
来源:构造杂题选做
因为字典序最小,所以不难想到每次贪心的填0,要做的就是判断填了0后是否有解。
这题是很强的结论题,首先可以证明一定存在一种解两个序列一定有一个的前缀最大值集合是原排列的前缀最大值集合的子集。
证明考虑如果两个序列都有非原来的前缀最大值,假设分别是 \(p_a\) 和 \(p_b\),那么必然是因为原排列中大于 \(p_a\) 的那个前缀最大值分配到了 \(B\) 序列中,对于 \(p_b\) 同理,所以可以交换 \(p_a\) 和 \(p_b\),这时两个序列非原来的前缀最大值数量各-1,得证。
不妨假设 \(A\) 的前缀最大值集合是原排列的前缀最大值集合的子集,相反的情况可以对称构造,现在假设已经构造过了前 \(i-1\) 位,考虑第 \(i\) 为是否能放进 \(A\) 中(即填0)。
具体的,设 \(ca,cb\) 为现在 \(A\) 和 \(B\) 中前缀最大值的数量,剩下 \(i+1\) 到 \(n\) 中原来的前缀最大值数量是 \(suf\),要放入 \(B\) 中 \(k\) 个,再放入 \(m\) 个非原来的前缀最大值,那么能加入当且仅当满足:
即
可以发现后面是常数,所以只需要把原来的前缀最大值看做2,非原来的看做1,维护 \(i+1\) 到 \(n\) 中是否存在一个和为 \(cx+suf-cy\) 的上升子序列。
不难发现,如果存在一个和为 \(x\) 的,可以通过删去 \(2\) 的方式得到 \(x-2\),但是不一定能够删去 \(1\) 得到 \(x-1\)。
所以对奇偶分别维护最大值即可,用线段树就可以实现了。
复杂度 \(O(nlogn)\)。
3.11
[AGC038F] Two Permutations
标签:网络流
来源:AT杂题选做
很难想的一道网络流题,不过这种数据范围和这种特殊限制很难是DP,大概就是图论的东西了。
排列是可以拆成若干循环的,发现每个点的选择是会影响到循环上的其他点的,所以把这些循环拆出来分别考虑。
对于一个环只有两种情况,要么变成 \(1->n\) 的形式,要么是 \(p_1 -> p_n\) 的形式,两种选择联想到二分图。
分类讨论,一共有5大类:
我们希望 \(a_i\neq b_i\) 的最多,所以希望 \(a_i=b_i\) 的最少,如果把一个 \(a_i=b_i\) 的选择定义为用1代价割开源汇点,那么对上面5种情况讨论一下建图跑最小割即可,具体如下:
二分图单位边权跑 dinic 复杂度是 \(O(n\sqrt n)\),所以这题复杂度为 \(O(n\sqrt n)\)。
4.9
[AGC012E] Camel and Oases
标签:状压
来源:AT杂题选做
首先 \(V\) 只有 log 种取值,这个自然 log 必定是要用到的。
这 log 种步长都可以预处理出若干连续段,容易发现连续段中任意两点可达,而且不同层之间的连续段具有严格包含关系。
于是问题变成了每一层可以选择一个连读段消掉,固定了第一层消掉哪个连续段,求是否存在一种方案能删掉所有元素。
一开始以为是用线段树维护贪心,写了个 3log 的东西,又T又WA。
考虑状压 DP,不过看上去连续段数量非常多,没法状压,不过如果第一层连续段的数量就多于 \(logV\) 了那么任何位置都是无解的,于是保证了状压复杂度的正确性。
设 \(f_s\) 表示用了 \(s\) 集合内的层中的某些连续段最多把左边前缀消掉多少,\(g_s\) 类似的定义在后缀上,注意 \(s\) 是不能包含第一层的。
那么就只需要看一下对 \(s\) 和 \(t[s\cup t=\emptyset]\) 是否再补上第一层被钦定的连续段后是否能把 \(1\) 到 \(n\) 完整覆盖即可。
复杂度 \(O(VlogVlogn)\) 。
[AGC035E] Develop
标签:计数DP
来源:AT杂题选做
题目限制很怪,不过写一个爆搜出来发现似乎不合法的状态选出来的数字很有规律,具体的建出来一个 \(x\) 向 \(x-2\) 和 \(x+K\) 的有向图后,选出来的点都至少包含一个简单环。
那么就有 \(O(2^n*n)\) 的做法了,直接枚举出来所有的简单环,再 fwt 一下即可,发现这个做法可以通过小样例,至少正确性是没问题的(前提是计数题)。
进一步分析,发现当 \(K\) 是偶数的时候,简单环是连续的一段数字,不难证明,于是可以对数字奇偶性分两组简单 \(O(n^2)\) 背包出来答案,因为是独立的直接相乘即可。
但是当 \(K\) 是奇数时就失效了,原因在于路径是形如走一个 \(K\),走若干-2,再走一个 \(K\),再一直走-2直到走出来环,这一过程第二步走-2的数量是不定的,但是一共走的 \(-2\) 数量必定是 \(K\),可以从这里入手。
建出来一张图,左边是奇数,右边是偶数,每个奇数向它 \(+K\) 后的偶数连边,然后把这些边变成水平的,容易发现所有横叉边平行。
这样就变成了只能往下或往右走,不能存在跨越横叉边的长度大于 \(K+1\) 的路径,求方案数。设 \(f_{i,j,k}\) 表示走到了第 \(i\) 层,跨过横叉边的最长路径是 \(j\),没跨过的是 \(k\),讨论一下转移方式,可以做到 \(O(n^3)\)。
[ARC121F] Logical Operations on Tree
标签:DP
来源:AT杂题选做
感觉自己做麻烦了,不过能A就行。
首先观察出一些性质:如果有两端都是0的边直接缩起来一定不劣。
对于1而言,如果边是或运算的话就可以对0起到"防御"作用。
于是问题变成了树上至少存在一个1能"防御"所有0的方案数,直接DP就好。
设 \(f_{i,j,k}\) 表示当前节点是 \(i\),如果是 \(1\) 是否下方都全"防御"的状态是 \(j\),子树内是否存在这样的1的状态是 \(k\)。
转移分类讨论即可,不需要任何优化。
复杂度 \(O(n)\)。
4.11
[AGC003D] Anticube
标签:数论,根号分治
来源:AT杂题选做
很厉害的根号分治题。
数据范围 1e10 启示要对值域根号分治,并且要三次根号,而题目的立方就很好对应了这一点。
容易发现题目要求选出来的任意两个数乘积的质因子指数不能全是3,可以先把每个数的质因子指数%3,这一步可以用 \(O(nV^{\frac{1}{3}})\) 的复杂度完成。
接下来把每个数剔除掉所有小于等于 \(\sqrt[3]{V}\) 的质因子剔除掉,记为 \(z1\),把 \(z1\) 的每个质因子指数 \(t\) 变成 \((3-t)%3\) 后记为 \(z2\),这一步之后对剩下的结果分类讨论:
直接开一个桶来统计,只需要开 \(O(V^{\frac{2}{3}})\) 即可。
这样就做完了,时间复杂度 \(O(nV^{\frac{1}{3}})\),空间复杂度 \(O(n+V^{\frac{2}{3}})\)。
4.12
[AGC021C] Tiling
标签:构造
来源:AT杂题选做
比较水的构造,自己想出来了。
首先可以把棋盘先拆出来若干 \(2 * 2\) 的小格,如果 \(n,m\) 不同时是奇数就直接做完了,因为最多会多出来一行或一列,容易证明这样已经构造满了。
但是当 \(n,m\) 都是奇数时,这样不一定是最优的,比如 3 3 2 2
,显然是有解的,但是如果按照先把第 \(n\) 行和第 \(m\) 列放满的策略会放不下。
很简单,先把第 \(n\) 行和第 \(m\) 列放满就好了,剩下的就是亿些细节处理(指WA了9发)。
4.13
CF1239E Turtle
标签:DP,贪心
来源:CF杂题选做
先用交换法可以证明第一行递增第二行递减答案一定不劣,可以通过讨论交换后对答案的影响证明。
定义一个函数 \(f(i)=a_{0,i+1}-a{1,i}\) ,表示如果在第 \(i\) 列从先向下再向右切换为先向右再向下的代价,通过第一步可以发现 \(f\) 递增。
也就是每一种拐点的方案价值从前往后是凸函数,也就是答案只在第一个位置拐和最后一个位置拐取到最大值(因为 \(f\) 的前几项可能是负数,所以也要考虑第一项的值)。
所以需要最小化 \(max(a_{0,1}+a{1,n}+\sum_{i=2}^{n}a_{0,i}, a_{0,1}+a{1,n}+\sum_{i=1}^{n-1}a_{1,i})\) 的值,提取出相同项 \(a_{0,1}+a_{1,n}\),那么就剩下的问题相当于把集合划分为相等的两部分使得最大值最小,这是个典型的 bitset 优化背包。
剩下的就是确定 \(a_{0,1}\) 和 \(a_{1,n}\) 的值,考虑把最小的两个值分配给他们,通过调整也许可以证明这样做一定不劣。
那么复杂度就是 \(O(\frac{n^2\sum a}{w})\)。
CF1285F Classical?
标签:数论,莫比乌斯反演
来源:CF杂题选做
Classical?
看到最小公倍数先转化成 \(\frac{a_i * a_j}{gcd(a_i, a_j)}\)。
考虑枚举 \(d\) ,转化为求最大的 \(a_i * a_j\) 满足 \(gcd(a_i, a_j)=d\)。
一种思路是二分+莫反,另一种思路是贪心+莫反,其中莫反都是用来求互质数的对数的,两者都是 2 个 log 的,二分的做法比较复杂,这里放一下贪心的做法。
把所有 \(d\) 的倍数提取出来,把除以 \(d\) 的结果从大到小排序,朴素的思路是枚举所有与当前数互质的数更新答案,这样做是数字数平方级别的,考虑用一个栈去贪心。
假如说能算出来比当前数 \(x\) 大且互质的数有 \(s\) 个,那么就考虑从栈中暴力弹出来 \(s\) 个互质的数为止,再加入当前的数。
考虑这样做的正确性,每个栈中的数字都会被第一个比他小且互质的数更新到,之后和它互质的数对答案没有作用,所以可以直接弹出。
那么剩下的工作就是求 \(\sum_{i} [a_i\geq x][gcd(a_i,x)=1]\),莫反即可,得到式子为 \(\sum_{d|x}\sum_{d|v}cnt(v)\),每次加入和弹出元素暴力维护式子的后半部分即可。
复杂度不会算,据说是 \(O(Vlog^2V)\) 的,个人感觉是 \(O(Vlog^3V)\)。
还有 \(O(VlogV)\) 的做法,也许某一天会补上。
[AGC010C] Cleaning
标签:图论
来源:AT杂题选做
一直以为是什么神秘贪心,后来猜测会不会是虚树,猜了不少结论,最后看题解才明白这是经典题。
先考虑一个模型:有若干正整数,每次选择两个不同的(位置不同)同时-1,问让所有元素变成0的条件。
显然,这些数的和是偶数,并且最大的数不能超过和的一半,证明就是每次选出最大和次大,直到出现0后递归到小规模等价问题,最后来到 \(n=2\) 必然有解。
回到本题,先进行转化,既然很难确定选择哪些叶子对,那就干脆不确定,也就是用类似DP的东西表达,设 \(f_x\) 表示从 \(x\) 的子树内要延伸出这么多路径。
先选择一个非叶节点作为根,对于叶子显然 \(f_x=a_x\),对于非叶子需要考虑子树内可以把一些叶子在自己这个节点合并出来而不向外延伸。
具体的,设 \(s_x=\sum_{y\in son(x)}f_y\),设合并的对数是 \(A\),继续延伸的数量是 \(B\),必须有 \(2A+B=s_x\),而继续延伸的就是 \(f_x\),所以有递推式 \(f_x=2A-s_x\)。
而我们希望更多的路径在子树内就已经合并,不去外面影响别人,所以我们希望 \(a\) 尽量大,这上界显然是 \(a_x\),继续思考,如果当前节点还有残留的,那么之后肯定也用不上了,那么就有 \(f_x=2a_x-s_x\),且要满足 \(0\leq f_x\leq a_x\),大于等于0是为了不能在当前节点有残留。
那么所有的 \(f_x\) 就都是定值了,直接 dfs 一遍就都能求出来了。
但是还没有做完,思考我们不能把来自同一颗子树的路径合并,那么就变成了有若干个正整数,每次挑两个不同的同时-1,使得最后都变成0,当然这里是有一部分可以不变成0,相当于把总和减去了 \(f_x\)。
那么就有 \(max_{y\in son(x)}f_y\leq frac{s_x-f_x}{2}\),化简得到 \(max_{y\in son(x)}f_y\leq a_x\)。
最后,根节点的 \(f\) 值必须为0,根节点没法再延伸出路径去合并。
把这些条件综合起来,注意特判 \(n=2\),毕竟这个做法的前提是找到一个非叶点作为根。
复杂度 \(O(n)\)。
[AGC043C] Giant Graph
标签:图论,博弈
来源:AT杂题选做
看到这样奇怪的点权就知道是从和最大的点贪心,但是实在是没想到这题会和博弈扯上关系。
最暴力的东西就是从大到小枚举点权和,如果这个点连出去的所有点都是没被标记的就标记它,答案就是被标记的点权之和。
观察这个条件,有点类似博弈必胜必败态的定义,如果某个点连出去的所有点都是必胜态就必败,否则这个点必胜,答案就是所有必败点点权之和。
发现这个博弈是一个有向图游戏,可以分三个维度拆成三个独立的游戏,每个游戏都是形如在图上走一步,没有出边可走者败,这个东西完全符合有向图游戏的定义,那么对三个有向图都算出来 sg 值后,答案就是这个点三个维度 sg 值异或和为0点权之和了,这个东西可以直接 FWT 。
但是观察到 sg 值不会超过 \(\sqrt n\),所以可以直接 \(O(\sqrt n * \sqrt n)\) 枚举两维,剩下一维是确定的,复杂度 \(O(n + n\sqrt n)\),后面是计算 sg 函数值的最坏复杂度(远远达不到)。
4.25
[AGC001D] Arrays and Palindrome
标签:构造
来源:AT杂题选做
很神秘的构造题。
看到回文串可以联想到把相等的字符建一条边,那么题目的要求等价于这个 \(n\) 个点的图最终形成一个连通块。
先考虑无解的条件,不难发现一个回文串限制 \(a_i\) 可以建出来 \(\lfloor \frac{a_i}{2} \rfloor\) 个边,所以奇数的数量不能超过2个,否则最基本的树都建不出来。
接下来考虑构造,从特殊出发,当 \(m=1\) 时,如果 \(n=1\) 的话 \(b\) 序列是 \(1\) 就好,否则 \(b\) 序列就可以是 \(1,n-1\)。
继续拓展,把所有奇数放在首尾,然后首+1,尾-1,发现就得到了一组解。
证明考虑如果把奇数放在中间,那么会导致两个位置相差1的奇数块,手动模拟发现是不连通的,继续分析是奇偶独立的,所以不能把奇数放中间。
并且考虑至少要构成一个树,所以 \(b\) 序列的奇数也不能超过2个。
复杂度 \(O(m)\),实现也非常简单。
4.26
[AGC052B] Tree Edges XOR
标签:构造
来源:AT杂题选做
一开始以为操作是可以选择出边的,那么可以构造出不影响其他边的获得任意点的点权的方案,以为是个线段树分治维护线性基,后来才发现读错题。
题目很像[APC001F] XOR Tree,考虑边权转点权,每条边表示为两个顶点的异或。
这个构造不难,随便定个根,强制让根的点权为0,那么每个点的权值就是到根的边权异或和。
那么最终得到两个序列 \(a,b\) ,分别是初始点权和最终要变成的点权。
考虑操作的变化,手动画图得到操作一条边相当于交换两端点的权值。
不难发现这两个序列需要同构,具体的,存在某个值 \(x\),使得 \(a\) 的每一项异或 \(x\) 和 \(b\) 排序后相等,证明考虑调整一个点的点权需要全局异或,如果两个序列同构一定可以通过若干次相邻点的交换得到最终要变成的点权。
复杂度 \(O(n+nlogn)\),瓶颈在排序。
[AGC052C] Nondivisible Prefix Sums
标签:计数DP
来源:AT杂题选做
很强的性质+计数。
首先和为 \(p\) 的倍数一定不合法,这个可以简单DP,具体的设 \(f1\) 表示和为 \(p\) 的倍数的集合数量,\(f2\) 表示不是 \(p\) 的倍数,有 \(f1'=f2\),\(f2'=(p-1)f1+(p-2)f2\)。
然后考虑所有和不是 \(p\) 的倍数的集合,假设1是出现次数最多的,如果不是1则全体乘上这个数的逆元(因为 \(p\) 是质数所以总是存在),接下来考虑一个策略:
假设不是1的数有 \(m\) 个,设为 \(b_1,b_2,……,b_m\),那么先放 \(p-1\) 个1,然后放 \(b_1\) ,再放 \(p-b_1\) 个 1,再放 \(b_2\),一直到 \(b_m\),如果剩下的 \(1\) 数量超过了 \(p-b_m\),那么多出来的1会发现总是无处可放的,反之我们就构造出了一个方案,所以可以证明这是充要条件,即1的数量 \(n-m\) 要满足 \(n-m\leq p-1+ \sum_{i=1}^m p-b_i\)。
计算合法的是不方便的,因为不等式右边上界非常大,所以转成计算不合法的减去就好了,这时的上界只有 \(n\),是可以接受的。
具体的,用一个DP求出来 \(f_{i,j}\),表示 \(b\) 序列有 \(i\) 项且 \(p-b_i\) 和是 \(j\) 的方案数,那么需要被减去的条件是 \(n-i-j%p!=0&&n-i>p-1+j\),还需要乘上组合数 \(C_{n}^{i}\) 表示在集合中挑出这 \(i\) 个位置,再乘上 \((p-1)\) 表示众数的种类。
特别的,当 \(b\) 是空序列时,需要特判一下,具体的就是看 \(n\) 是否是 \(p\) 的倍数并且 \(p\leq n\),这时全1序列是不合法的,需要减掉 \((p-1)\)。
\(f\) 的DP可以前缀和优化到 \(n^2\),那么复杂度就是 \(O(n^2)\) 的。