8月杂题
Cu 傻逼 来写自己最后一个赛季的第一篇博客啊。
感觉以前自己写博客多少有点装逼的目的,现在会尽量写简练一些。
1.CF1225G To Make 1
直接 dp 复杂度寄了啊,考虑找点性质。
有解的必要条件就是存在一组 \(x_i\) 使得 \(\sum \frac{a_i}{k^{x_i}}=1\) 对吧,其中 \(x_i\) 可以看作是一个数在合并过程中被除的次数。
这个其实就是充分的啊。考虑设 \(M\) 是 \(x_i\) 的最大值,那一定至少存在两个 \(x_i=M\) 啊,否则和不可能是 \(1\) 。然后把这俩合并,归纳下去就好了。
所以就转化成找 \(x\) ,就很 trivial 了。
2.AGC032D Rotation Sort
考虑这个区间左/移,实际上可以看成是一个数的移动啊。
先考虑 \(A=B\) 怎么办啊,那就是让移动次数尽量少,那有些数就在站桩,这些桩分成若干段,剩下的数移到对应的位置啊。这个桩还要构成上升子序列。那这个就是求 LIS 。
\(A,B\) 不一样咋个搞啊,考虑中间某个数,左右的桩是 \(l,r\) 的话,如果 \(x<l\) 就往左移,\(x>r\) 就往右移,这是显然;如果存在 \(l<x<r\) ,那让 \(x\) 一起站桩明显更优啊。
就 dp 算算,trivial 了。
3.CF1523F Favorite Game
就首先有个简单 dp 啊,就是 \(f_{S,i,j}\) 分别表示传送门集合,所在的点,当前完成的任务数,那这个太爆了,考虑优化。
如果你站在某个传送门上,那因为这是传送门,所以你不关心你在哪个传送门,就是 \(f_{S,j}\) 表示:传送门集合,完成任务数,值为最小时间。
如果你站在某个任务点上,那这个时间是固定的啊,所以你只关心完成任务数,就是 \(g_{S,j}\) 表示:传送门集合,当前所在任务,值为最大任务数。
啊这个又做完了,互相转移一下就好了啊。
4.ARC113F Social Distance
这个期望先拆成 \(\int_{0}^{\infty}P(X\geq a)\,da\) 啊,这个相当于是 \(y_i\) 范围在 \([x_{i-1},x_i-(i-1)a]\) ,然后需要 \(y_i\le y_{i+1}\) 啊。
固定 \(a\) 的话,你按值域做个扫描线,设 \(f_{i,j}\) 表示到第 \(i\) 段,有 \(j\) 个数已填的概率。转移就是枚举有多少数在当前填了啊。这是 \(O(n^3)\) 的。
然后 \(a\) 没有固定啊,但只要每个分界点大小关系相同,答案就是个关于 \(a\) 的多项式啊,\(a\) 就可以分成 \(O(n^2)\) 段,每段内算出来个多项式积分一下就好了。
把维护的 dp 值换成这个多项式就行了啊。然后复杂度就是 \(O(n^6)\) 的捏。
5.P7295 [USACO21JAN] Paint by Letters P
就是逼数学题啊。就这种平面图的联通块个数,有个欧拉公式啊,就是说 \(F-V+E=C+1\) 啊,\(F\) 是点数,\(E\) 是边数,\(V\) 是区域数,\(C\) 是联通块数啊。
来看这个题,就转化成求子矩阵的图构成的区域数啊。
这个就相对好做了:先把整张图的所有区域求出来,对每个区域随便标记一个块。查询的时候先求个二维前缀和;再减掉不合法的情况啊,那这些不合法的区域它们一定跨过了子矩阵的边界。
所以就枚举边界的每个块块,减掉它所在区域的贡献即可,注意不要减重了哟,复杂度 \(O(nm+nq+mq)\) 。
6.AGC058F Authentic Tree DP
你妈的想到了是有组合意义结果没想到这么逆天的构造啊。
考虑如果除的是 \(n-1\) 答案就是 \(1\) 了啊,为什么呢,这个实际上可以当成是,每次随机选个边删掉,然后两个子树分别做。让整个过程整体一点,就是确定一个删边的排列啊。
但现在除的是 \(n\) 啊怎么办呢。删的是边,但 \(n\) 是点数。如果除的是 \(2n-1\) ,那其实我们把每个边也看成点,这个“边点” 与两个端点相连,就 over 了。
就相当于我们这个排列需要每个边点在两个端点之前出现。容一容,树形 dp 一下就搞完了。
但你他妈的除的是 \(n\) 啊。如果我们让总点数在模意义下也是 \(n\) 是不是其实也可以?
现在就是神来之笔啊,真没想到啊:我们在每个“边点”下面接 \(mod-1\) 个虚点就 ok 了。复杂度 \(O(n^2)\) 。
7.hdu7344 Coloration
感觉对费用流建图的理解更好了点啊。
首先这个题意很好翻译,就是有一些操作,以一个费用给叶子到某祖先的一条链 +1 ,使得每个点的权值在一个范围内啊。
那我们考虑费用流啊,就是从每个叶子出发往上引个流,利用拆点建边搞上下界,但是这个流必须在某个地方停止啊怎么办呢。
那其实我们考虑要让整个图流量平衡,我们直接让这个流流回起点就平衡了啊,就跑个上下界可行费用流就好了。
就感觉很少做这种无源汇的图啊,其实有源汇就是个手段啊,自己对 flow 理解不深。
8.UOJ811 璀璨宝石
好妙啊哥。主要是对问题的勾勒方法吧,还有一些状态划分的技巧。
就是说我们有一个固有想法,就是最后求 \(\max (a,\frac{sum}{2})\) 这么个东西。
但这个路走不通啊,我们没法记下来那么多信息。所以我们想能不能边丢石子边消啊。
假装我们开天眼了,知道当前每种石子还要消多少次啊,那我们一开始能乱找两个消啊,然后消到某个时候出现了个极大的,就是让这屌和其他的消。
但我们没开天眼。但我们知道消的过程就是前后这两个阶段了,而且随便找个地方切状态就行了,因为我们是要最优化啊。
这个题就 trivial 了啊。
9. P4558 [JSOI2018] 机器人
不难先把矩阵无限复制,然后考虑每一条对角线,如果存在两个格子出边方向不同肯定 g 了,所以是得相同的。
又由于我们无限复制了,其实第 \(i\) 条和第 \(i+n\) 条,第 \(i+m\) 条的方向都要相同。由此发现这个机器人的走法是有一个 \(gcd(n,m)\) 的周期的。
由于 \(gcd(n,m)\) 是 \(nm\) 的约数,可以发现此时每个格子恰好走一遍等价于:从 \((0,0)\) 出发,走 \(nm\) 步后恰好第一次走回 \((0,0)\) 。
后面就 trivial 了。
10.CF1458C Latin Square
有点意思,就是把每个格子当成一个向量 \((a,b,c)\) ,分别表示横纵坐标和格子上的值。
则每次变换都是对它乘一个矩阵,这个题就做完了。
11.ABC314Ex Disk and Segments
正常的想法是先二分答案,再判有没有一个点能被所有区域包含,每个区域长成:一个长方形,两头接半圆的样子。
但是爷不会维护这种区域。踌躇莫展时突然想到了把这个东西看成一个二元函数,就发现了它的凸性,两遍三分做完了。
12. AGC064D Red and Blue Chips
比 C 好搞。就是考虑一个终止状态,怎么 check 它合不合法,倒看操作,每次遇到一个 B ,就可以把之前的一座塔劈成两半,R 相当于在某个塔的顶部取数。
怎么刻画这个东西呢,我们发现我们只关心哪些 B 是所在塔的最上端的 B 。进一步的,我们发现每个 B 都有一个权值,代表取它时附带的 R。
我们每次会尽量取权值大的。整个题就转化成了数列问题,就是前 k 大的数之和要大于 \(a_k\) 的形式。trivial 了。
13.ABC313F Flip Machines
看到 N 是 40 ,不难想到折半,但是直接折半没啥用啊。哎是不是可以正负分开,取小的来枚举就可以了。确实是这样的。
14.ARC126E Infinite Operations
趣味,就是考察 \(S=\sum |a_i-a_j|\) 这么个东西,发现每移动 \(x\) ,\(S\) 就会减少 \(2(2k+1)x\) ,其中 \(k\) 是插在 \(i,j\) 间的数个数。
显然 \(k=0\) 最好,这样得到答案就是 \(\frac{S}{2}\) 。
15.牛客多校9.C Puzzle: Kurodoko (Max)
在最后一分钟绝杀,爽死了。
先想的是以直径的两端为突破口,一定会取 \(a\) 尽量大的两个当直径。但是想了想不太行。
后来考虑到,可以根据最远点在直径的哪头,把树劈成两半,就考虑从中间这个边拓展了。
这个时候就豁然开朗了,中间这两个点需要 \(a_u+a_v=len+w\) ,剩下每个点 \(u\) 需要找到一个父亲,使得 \(a_u=a_v+w\) 。还需要两头都存在一个点,它的 \(a\) 是最大的。
考虑枚举中间这个边,不难发现要取两条不交路径,其中终点固定,起点在给定的某个范围内。直接跑 flow。
但是中间的边可能很多啊。但我们发现 \(a_i\) 最小的 \(u\) 一定会在中间的边上,否则它是找不到父亲的。
由此,发现整个问题终点有一个固定,另一个在某给定范围。这样就可以了,由于只 flow 两轮,复杂度线性。
15.牛客多校9.F Non-Puzzle: The Lost Array
好题啊。首先考虑需要满足这个 num 的限制,我们一定会依次每个权值搞。而不是依次每个位置。
由此我们有这样一个 dp ,我们依次枚举每个权值,记下来当前有哪些位置填了,以及当前 num 数组的桶,转移枚举子集。
发现可能的桶是很少的,具体的 \(\le 72\) 个。复杂度 \(O(3^nnm*72)\) 或者 \(2^nn^3m*72\) ,总之不能通过。
问题出在我们需要把当前填了的位置记下来,带来了很大的不便啊。如果没有 [每个位置只能填一次] 的限制就好了啊。考虑直接在一开始容斥!
这个题就做完了,复杂度 \(O(2^nnm*72)\) 。
这个想法很像 [ZJOI2016] 小星星。
16. hdu7333 Cut The Tree
先求出全局最优的点对 \((u,v)\),发现我们只用关心根到 \(u\) 链的答案,根到 \(v\) 链的答案,做完了。
17. P6646 [CCO2020] Shopping Plans
水群看到一直在说 shopping 很牛逼什么的就来看,发现确实很牛逼啊啊。
先考虑只有一个种类该怎么做呢。先把物品从小往大排序,最好的取法就是取前 \(L\) 个,接下来我们尝试从它开始,拓展到其他状态。
我们设计一种方式来到达:假设最后我们取了 \(x_1,x_2,...,x_m(m\le R)\) ,则我们先依次取 \(L+1,R\) ,再把 \(m\) 移到 \(x_m\) ,\(m-1\) 移到 \(x_{m-1}\) ... 这样移。
发现这样子走,每一步总权值都不降,我们就把它抽象成一个图,每个路径代表一种方案,类似于 dij 跑一遍。(现在图其实长成了一棵外向树)
但这样搞的话每个点都要记录 \(O(n)\) 的信息,不好。我们尝试对状态进行简化,发现我们只关心四个信息:
正在移的是第 \(i\) 个;当前已移到 \(j\) ; \(x_{i+1}\) 的值 \(k\),当前的总权值 \(s\)。这个时候图形成了一张 DAG ,我们仍然用 dij 跑就行了。
然后现在有很多种类怎么办呢。类似地,所有种类取最优的种类出发,依次对每个状态做调整。
可以抽象成,我们当前把第 \(i\) 种调整到了第 \(j\) 优取法 (j>1,否则会算重),当前总和 \(s\) 。则可以把 \(j\) 移到 \(j+1\) ,也可以取 \(v>i\) ,然后把 \(v\) 从最优调整至次优。
但这里就有个问题,我们直接枚举 \(v\) 就 g 了。接下来有个神来之笔,就是我们把这个点的出边从小往大排序(也就是把次优-最优排序)。
然后修改连法,如果对第 \(i\) 个连 \(w_i\) 的边,我们就调整成:从 \(1\) 连了 \(w_1\) ,\(i\) 往 \(i+1\) 连 \(w_{i+1}-w_i\) 。这样就做完了。