贪心做题记录-2
CF1477D. Nezzar and Hidden Permutations
若一个点的度数为 \(n-1\),则其在 \(p,q\) 中的位置定然相同,因此可以先将这个点删去,缩减为子问题,直到剩下 \(n'\) 个点且所有点的度数都小于 \(n'-1\)。结合这个性质考虑图 \(G\) 的补图 \(K_{n'}-G\),此时补图中的所有连通块大小都 \(\ge 2\)。
发现如果补图是菊花的话一定可以构造出一个各个位置都不相同的解:根节点在 \(p\) 中放置 \(1\),\(q\) 中放置 \(n\),叶子节点在 \(p\) 中放置 \(2,3,\cdots,n\),在 \(q\) 中放置 \(1,2,\cdots,n-1\)。由于这个构造只有根节点和叶子节点的大小关系不一致,但根节点和叶子节点在补图中有边,说明其在原图中无边,大小关系不会影响答案。
事实上,任何一棵树都可以划分成若干个 \(\ge 2\) 的菊花,参照下面的过程即可给出一组合法解:
从根节点开始递归枚举每个点 \(u\),若其目前不属于任何一个菊花,考虑以下过程:
- 若和其相邻的点中存在点不属于任何一个菊花,将 \(u\) 作为根,和 \(u\) 相连的不属于任何一个菊花的点作为叶子构造一个菊花。
- 否则,随便挑一个点 \(v\)。若 \(v\) 是其所属菊花的根,直接将 \(u\) 加入 \(v\) 所属的菊花即可。否则若 \(v\) 所属的菊花的大小 \(> 2\),将 \(v\) 移出原来的菊花,和 \(u\) 一起作为一个菊花即可,根是谁都可以;否则,将 \(v\) 置为其所属菊花的根节点,将 \(u\) 加入 \(v\) 所属的菊花即可。
由于上述过程总是产生一个合法菊花,且不会使任何一个合法菊花变得不合法,因此可以给出一组合法解。
现在对于每一个菊花都可以在内部给出一个构造,而对于菊花之间的边,只需要菊花间的大小关系始终相同,因此让各菊花的值域连续即可满足条件。
最后的问题是如何找出补图的一个生成树森林。可以将当前在图中还未加入生成树且不和自己连边的点视作自己在生成树上的儿子,然后递归解决问题。枚举到一个点不将其加入生成树森林最多发生 \(m\) 次,用 set 维护当前的未加入生成树的点即可。复杂度瓶颈在这里的 \(O(n\log n)\)。
CF1290D. Coffee Varieties (hard version)
先考虑如何统计答案,不难想到将 \(i\) 和 \([1,i-1]\) 中的所有数比较,如果有数字相同,那么这个数不计入贡献。显然只会在所有数字第一次出现时统计贡献,答案自然正确。然而在不加任何优化的前提下,查询的次数是 \(O(n^2)\) 的。
考虑这个做法没有利用到 \(k\),不难想到如果对 \(k\) 分块,在将某个块加入队列的过程中,自然可以知道每个点在块内的前缀是否出现,现在只需要考虑块间的查询。然而因为每查询一个数就会从队列中弹出一个数,因此有效查询位数只有 \(1\) 次。考虑若对 \(w\) 分块,有效查询位数就是 \(k-w+1\),不妨让两者平衡,即令 \(w=\frac{k}{2}\),此时有效查询次数足够查询一个块中的所有元素是否在另一个块中出现。于是可以枚举 \(i,j(i<j)\),对于每两个块互相查询一次。若分成 \(m\) 块,查询次数是 \(\frac{km(m-1)}{2}\) 左右,清空次数是 \(\frac{m(m-1)}{2}\)。代入 \(m=\frac{2n}{k}\) 可以得到查询次数是 \(\frac{2n^2}{k}\),清空次数是 \(\frac{2n^2}{k^2}\),支持通过 easy version。
考虑其实每次清空并不优,因为这个信息也可以用来查询后面的块,即枚举完 \(i,j\) 后,可以继续选择一个块 \(k(j<k)\) 获知 \(j,k\) 之间的贡献。即使获得的信息是 \(i\) 提供的,由于 \(i<j<k\),因此这个信息也是有效的。这样除了清空后的第一次查询,每次查询可以省去约 \(\frac{k}{2}\) 的操作。一个容易想到的划分方法是枚举间距 \(L\),每隔 \(L\) 个块查询一次,这样总共有约 \(\frac{m(m-1)}{4}\) 条查询链。查询次数是 \(\frac{km(m-1)}{4}+\frac{km(m-1)}{8}\),清空次数是 \(\frac{m(m-1)}{4}\)。同理代入得查询次数为 \(\frac{3n^2}{k}\),清空次数为 \(\frac{n^2}{k^2}\),可以通过这道题。
LG8425. [JOI Open 2022] 长颈鹿 / Giraffes
对于区间 \([l,r]\) 考虑其最小值 \(L\) 和最大值 \(R\) 的位置:若 \(L,R\) 均不出现在 \(l,r\) 上,那么这两个数分别满足两个条件,因此区间 \([l,r]\) 的观感是差的;否则,区间 \([l,r]\) 的观感是好的。这意味着对于任何区间,其值域的最小值和最大值至少存在一个位于端点处。
对这个内容 dp,即找到和原排列 \(p\) 相差位置最少的符合条件的排列 \(q\)。考虑如何生成一个 \(q\):每次从剩余数字中选择最大值或最小值填到剩余位置的最前面或最后面。于是可以设 \(f(l,r,x)\) 表示当前还没有填 \([l,r]\) 上的数,可以填的数字的最大值为 \(x\) 时和原排列不同位置的最小值,枚举 \(4\) 种情况转移即可,复杂度是 \(O(n^3)\) 的。
考虑将排列视作点 \((i,p_i)\) 转到平面上。在刚才的构造过程中,每确定一个位置值域范围就会减少 \(1\),并且下标和值域的范围始终连续,可以考虑用矩形来表示,并且可以发现所有的矩形都是正方形。继续发现性质,可以看出一个合法排列对应的 \(n\) 个正方形互相包含,并且 \(p_i=q_i\) 当且仅当 \((i,p_i)\) 出现在 \(q_i\) 对应的正方形的顶点上。因此,为了让相同的位置最多,就要让从原序列保留下来的相互包含的正方形最多。因此,转设 \(f(i,o,l)\) 表示以 \(i\) 为顶点的边长为 \(l\) 的第 \(o\) 种正方形最多能在里面保留多少相互包含的正方形,共有四种正方形分别代表 \(i\) 是正方形的左下角、右下角、右上角、左上角,枚举从哪个点转移来可以做到 \(O(n^3)\)。
此时还没有用到排列随机生成的性质。事实上,在随机生成的情况下,可以证明最多保留 \(O(\sqrt{n})\) 个相互包含的正方形。考虑一个合法排列可以分成一个递增子序列和一个递减子序列,那么在原序列上保留的位置也可以分成一个递增子序列和一个递减子序列,所以在原序列上保留的位置数量不超过最长上升子序列和最长下降子序列的长度和。而一个经典的结论是随机排列的最长上升子序列的长度是 \(O(\sqrt{n})\) 的,于是保留的正方形数量也是 \(O(\sqrt{n})\) 的。这启发我们交换定义域和值域,设 \(f(i,o,k)\) 表示以 \(i\) 为顶点的第 \(o\) 种正方形若想要包含 \(k\) 个相互包含的正方形所需的最小边长。依然可以通过枚举转移点做到 \(O(n^2\sqrt{n})\)。但这个做法常数很大,因此无法通过。
考虑快速求解转移。问题相当于有 \(O(n)\) 个正方形,以某个点为顶点的第 \(o\) 种正方形包含至少一个正方形的最小边长。以求解以给定点 \((s,t)\) 为左下角的正方形的最小边长为例,考虑一个给定正方形的左下角 \((x,y)(x\ge s,y\ge t)\),若这个正方形的边长为 \(l\),那么想要覆盖这个正方形的所需边长为 \(\max(x-s,y-t)+l\)。这就是一个二维偏序问题,考虑对 \(\max\) 中的内容分类讨论,将一个正方形拆成两个三角形,然后斜着扫描线维护后缀最小值,单次转移可以做到 \(O(\log n)\)。于是整体复杂度是 \(O(n\sqrt{n}\log n)\),可以通过。