Solution Set #7

来成都集训了几天,模拟赛仍然只会签到分。

好菜啊/ll

118 loj2839. 「JOISC 2018 Day 3」安全门(DP 状态设计,分类讨论,括号序列)

非常厉害的 DP 题,搞了两天终于讨论清楚情况了。

考虑一下合法的 \(S'\) 的条件。利用折线刻画括号序列,不妨假设存在 \(j,k\) 满足 \(j\) 是最小的点满足 \(s_{j+1}<0\)\(k\) 是最大的 \(k\) 满足 \(s_{k+1}<s_n\)。那么翻转的区间 \([l,r]\) 需要满足 \(l\leq j,r\geq k\),否则显然翻完之后会存在 \(<0\) 的位置。

现在我们需要找到 \(s_{r}-s_{l-1}=\frac{s_n}{2}\) 的区间,假设 \([0,j]\) 的前缀最大值是 \(x\)\([k,n]\) 的后缀最大值是 \(y\),那么最优的决策在前缀找一个 \(z=\min(x,y-\frac{s_n}{2})\) 的点,那么假设 \((j,k)\) 的最大值是 \(w\),需要满足 \(2z\geq w\)

分三部分 DP,钦定 \(x\leq y-\frac{s_n}{2}\),另外的情况可以通过翻转字符串转化。\(f_{i,j,k}\) 为第一部分,表示 \(x=j,s_i=k\) 的方案,\(g_{i,j,k}\) 为第二部分,表示限制最大值不超过 \(2j\) 的方案。第三部分倒着处理,设 \(h_{i,j,k}\) 表示 \(s_i=s_n+k\),最大值为 \(s_n+j\) 的方案数,在转移的时候把 \(g\)\(h\) 拼起来,后缀和优化一下。

但是 \(j,k\) 不存在的情况没有处理。如果 \(j,k\) 均不存在,则为计数合法括号序列的方案。否则,假设 \(j\) 不存在,即所有 \(s_i\geq 0\),原先的 DP 不再使用,考虑设计新的 DP。

此时我们需要考虑包含关系的问题。\(r\) 一定选择后缀最大值,但是 \([l,r]\) 未必包含全局最大值。可以设计一个新的 DP:设 \(f_{i,j,k}\)\(j\) 表示 \(s_l\) 的最小值,那么需要满足的条件是 \(2s_l\geq k\),可以动态维护,计入答案的时候拼上 \(h\) 即可。

提交记录 #1973394 - LibreOJ (loj.ac)

本题状态设计新颖,是不错的 DP 题就是有点太难讨论了

119 loj3228. 「USACO 2019.12 Platinum」Tree Depth(DP 优化)

设计状态:

  • \(f_{i,j}\) 是一个二元组,表示长度为 \(i\) 的,逆序对为 \(j\) 的排列的方案数和单调栈元素数。
  • \(g_{i,j}\) 表示长度为 \(i\) 的排列补全成长度为 \(n\) 的排列,增加 \(j\) 逆序对的方案数。

讨论钦定的最大值在哪边,把 \(f,g\) 拼起来,可以做到 \(\mathcal{O}(n^3)\)

提交记录 #1973510 - LibreOJ (loj.ac)

我尝试算 \(g\) 的单调栈元素数量,只能做到四方。其实算方案的时候我们是只在意一边的和的。

120 loj6777. 「2021 营员交流」大毒瘤(结论优化复杂度)

结论:每一时刻最多有 \(\sqrt{n}\) 个连续段,考虑连续段长度互不相等可以证明。

所以相当于每次最多只会增加 \(\sqrt{n}\) 个着火的方块。所以可以暴力维护火的蔓延情况,分块维护一下就好了。

提交记录 #1973855 - LibreOJ (loj.ac)

121 loj3770. 「USACO 2019 US Open Platinum」Valleys(平面图问题)

欧拉公式做法太糖了,写一下 1kri 老师做法。

唯一的问题在于判断是否有被完全包含的白色八连通块。考虑如何快速判断与一个黑色格子相邻的白色格子是否被完全包含,事实上只需要判断黑色联通块和白色连通块能够到达的最左侧点即可(AGC010E 的思路)。

倒着合并白色连通块可以确定每个黑色格子包含的连通块,正着合并黑色连通块的时候,判断当前连通块黑色格子包含的白色连通块是否被填满即可,只需要记录高度。

提交记录 #1973889 - LibreOJ (loj.ac)

然而我直接欧拉公式爆过去了。

122 qoj5071. Check Pattern is Good

做一些简单的问题转化:

  • 翻转 \((i+j)\bmod 2=1\) 的所有方格,这样问题转化成最大化四个格子相同的位置数量。
  • 考虑 WB 的交界位置的轮廓线。发现四个格子不合法当且仅当轮廓线经过了中间的点。

所以要最小化轮廓线的点数。

注意到若相邻的点位于不同的集合,意味着边上的两个点都必须被包含。考虑最小割,每个方格向它四个角上的点连边,需要割掉一些点,要求所有已知的 WB 位置不连通。点拆边直接做即可。

Submission #301202 - QOJ.ac

123 qoj6299. Binary String

先考虑 \(1\) 的个数不超过 \(\frac{n}{2}\) 的情况,此时当所有 \(1\) 不相邻的时候,串就是当前串的循环移位。可以发现,在存在 \(1\) 相邻的时候,串互不相同(你注意到,如果把 \(0\) 连续段从大到小排序,那么字典序是递减的)。所以只需要算多少次操作之后所有 \(1\) 不相邻。

考虑另一个暴力算法:设 \(A_i\) 为一个 \(01\) 序列,\(A_{i,j}\) 表示 \(i\) 在第 \(j\) 次操作是走还是停。那么考虑两个相邻的数 \(x,y\)\(A_y\) 的前 \(y-x-2\) 个数会是 \(1\),之后的所有位置都由 \(A_x\) 的第 \(y-x-2\)\(0\) 后面的部分复制而来。

所以可以直接记录 \(f_i\) 表示 \(A_i\) 最后一个停的位置,\(g_i\) 表示 \(A_i\) 中停的个数。那么 \(f,g\) 均可以封闭转移,答案是 \(\max f_i\)。环的问题断环为链即可。

如果 \(1\) 的个数多于 \(\frac{n}{2}\),可以把 \(01\) 翻一翻。

Submission #301296 - QOJ.ac

124 一个经典的计数问题

题目大意

咋想到的。

钦定操作只会删去末尾的 \(0\) 和开头的 \(1\),那么操作相当于删去一个 \(01\) 然后改成 \(0\) 或者 \(1\)(如果我们再开头加一个 \(0\),结尾加一个 \(1\)

考虑怎么计数。在任意两个数之间加一个标记,删除 \(01\) 的时候把标记删掉,考虑计数标记删除的时间。条件是对于一排 \(0\),右边比左边先删。对于一排 \(1\),左边比右边先删。套用 不等关系 的做法即可。

古希腊掌管原题的神 verdandi 找到了题目来源

125 2024.1.11 考试 road

题目大意

竞赛图三元环计数结论:\(\binom{n}{3}-\sum \binom{d_i}{2}\),其中 \(d_i\)\(i\) 的出度。

扫描线搞一搞。

126 2024.1.11 考试 graph

题目大意

考虑随机化。把点随机染色,并钦定所有边都连接两个不同颜色的点。可以使用费用流解决问题。

这样单次错误概率是 \(1-\frac{1}{2^k}\) 的,由于 \(k\) 比较小所以多随几次可以保证正确。

127 2024.1.11 考试 jigsaw

题目大意

转而考虑一个数会被经过多少次,或者说 \((a,b)\) 会在哪些 \((i,j)\) 中出现。

\((a,b)\) 的前驱是 \((a,a+b)\) 或者 \((a+b,b)\),考虑序列 \(\{a,a+b,b\}\),发现找前驱相当于把相邻两个数的和插到两个数之间,所有的分数就是在任意时刻相邻的两个数。在后出现的数统计答案,在它前面恰有两个元素与它相邻,所以对于每个数 \(ia+jb(\gcd(i,j)=1)\),它恰好对应两个元素。

所以答案式子是:

\[\sum_a\sum_b\sum _i\sum_j[\gcd(i,j)=1][ia+jb\leq n] \]

对其反演可以做到 \(\mathcal{O}(n\log n)\)

125 与 127 都是计数中映射思想的体现。

128 qoj5439 Meet in the Middle

对第一棵树边分治转化问题,询问的时候枚举每一层,然后相当于询问 \(d_a+d_u+\text{dist}_2(u,b)\) 的最大值。

相当于在第二棵树上挂一个叶子 \(d_u\),维护点集直径即可。

Submission #303169 - QOJ.ac

129 qoj5367. 递增树列

考虑一种判断合法的方式:先考虑 \(\text{lca}=1\) 的相邻点对,它们一定满足相邻两个结点不在 \(1\) 的同一个儿子的子树里面。如此循环,直到除了一个子树之外,其余的子树中的结点都出现过。此时我们往这个子树里面递归,重复上述过程。

考虑 DP。设 \(f_{u,i}\) 表示 \(u\) 子树中,有 \(i\) 个结点已经在之前出现过(满足 \(\text{lca}(p_i,p_{i+1})\)\(u\) 祖先的 \(p_i\) 个数)。如果转移到 \(f_{v,j}\),则我们先构造其余子树的排列,然后构造 \(v\) 子树中的点。一个子树中的点分为两类:在之前出现过,在 \(u\) 处出现,称为一类和二类。一类点没有限制,二类点需要满足不相邻的限制。对于第二类点容斥,引出一个 DP 状态:\(g_{i,j}\) 表示钦定了 \(i\) 个结点在之前出现过,\(j\) 个结点(容斥后,即把一些结点捆在一起后的点数)在 \(u\) 处出现。可以转移。

在出现过的深度最大的 LCA 处统计答案,复杂度可以分析出 \(\mathcal{O}(n^5)\),常数较小。

Submission #303600 - QOJ.ac

写了一年啊啊啊啊啊,完全不会写这种巨大 DP。

130 qoj6119. Frustration and Bracket Sequences

括号题。

首先在开头和结尾加的括号数量是确定的。然后交换次数可以考虑一个贪心:遇到右括号就检查前面有无空闲的左括号,没有就加入待定序列;遇到左括号就把前面所有右括号往后挪一位,然后匹配一个右括号。

考虑第 \(i\) 个右括号往后移动了多少位,设它前面有 \(b_i\) 个左括号,那么它移动的次数就是 \(\max(i-b_i,0)\)

把右括号看成 \(1\),左括号看成 \(-1\),问题变为求大于 \(0\) 的前缀和的和。直接分块维护,复杂度 \(\mathcal{O}(q\sqrt{n})\)

Submission #303697 - QOJ.ac

131 CF1097E Egor and an RPG game

尝试给出一个 \(k\) 的下界:构造排列 \(\{1,3,2,6,5,4,10,9,8,7,\cdots\}\),可以发现一个下界 \(\max\{k|\frac{k(k+1)}{2}\}\)

尝试构造这个下界。考虑原序列的 LIS,分情况讨论:

  • \(\text{LIS}\leq k\),根据 Dilworth 定理,可以找到一个下降子序列的不超过 \(k\) 的划分。
  • \(\text{LIS}>k\),可以直接把 LIS 拆出去,仍然合法。

复杂度 \(\mathcal{O}(n\sqrt{n}\log n)\)

Submission #241362107 - Codeforces

132 uoj461. 新年的Dog划分

由于原图联通,尝试找原图的一棵生成树。找到生成树之后,可以得到二分图的两部。

考虑找到生成树之后如何判断图是二分图。先把所有异侧非树边删掉,剩余的边均为同侧边,枚举树边,如果删掉树边之后图仍然联通,那么一定有同侧边。

那么考虑如何找到生成树。

暴力的做法是每次尝试删边,不连通则加入树边。考虑优化,对于每个点二分,每次删掉一个前缀的所有边,找到最短的前缀使得图不连通,那么前缀末尾的边一定可以作为一条树边。询问次数为 \(n\log n+n\),常数比较小。

提交记录 #673233 - Universal Online Judge (uoj.ac)

133 uoj386. 【UNR 3】鸽子固定器

考虑暴力的做法:从右往左扫描所有左端点,然后枚举右端点,用堆维护前 \(m\) 大的点。

考虑一个优化:如果左端点被弹出,那么一定不优,可以结束循环。

基于此,我们可以证明加入堆的次数是不超过 \(\mathcal{O}(nm)\) 的。考虑左端点 \(l\) 和加入数 \(u\)。若 \(a_u>a_l\),则 \(u\) 的个数不超过 \(m\);否则 \(a_u<a_l\),那么 \(l\) 前面至多 \(m\) 个这样的 \(u\),否则 \(l\) 不会入队。

使用链表维护,总时间复杂度 \(\mathcal{O}(nm\log m)\)

提交记录 #673252 - Universal Online Judge (uoj.ac)

posted @ 2024-01-15 07:33  yllcm  阅读(211)  评论(0编辑  收藏  举报