Atcoder 中高分段 选做 与 ARC vp

发布时间 2023-11-17 20:22:04作者: 寂静的海底

开坑,主推红题和铜牌题,来源乱七八糟,目前一部分来自学校给的。

一眼秒了标绿,想了很久或是接受了提示标蓝,看了题解或者认为题很难标红。意义重大标星。很主观(然后发现其实基本上大多数题都不会,狠狠地难过了)。

以后有时间可能会开始板刷 ARC,现在,还是,慢慢来吧。

upd-2023-10-30:和 Eray 随机刷 ARC 了qwq,有空会来做几场。

Atcoder 中高分段选做

——来源极其混乱

\(\color{blue}{\text{ABC252H}}\)

Tag: \(\text{Meet-In-The-Middle,Trie,搜索}\)

2023/9/11

求数异或出来的集合一看就很 \(\text{NPC}\),直接考虑非多项式做法。

状态量是 \(\prod cnt_i\),其中 \(\sum cnt_i=n\),这玩意儿相当于 \((1+x)^{\frac 1 x}\),取 \(e\) 时最大,因为是整数取所有 \(cnt=3\) 的时候状态量最大约为 \(W =3^{22}\times 4 \approx 10^{11}\) 级别,这个级别肯定没法搜出来,考虑给它开个根,用 meet-in-the-middle 搜。

将颜色分为两个阶段,\(S_1,S_2\) 其状态大致量都为 \(O(\sqrt W)\) 级别,暴力搜出来。

接下来的问题就是对于第一个阶段选择的值 \(a_x\),第二个阶段选择的值 \(b_x\),所有 \(a_i\oplus b_j\) 中的第 \(k\) 大,这是简单的:一棵 Trie,然后从高位到低位判断每位填 \(1\) 的数是否不多于 \(k\),不多于就填 \(0\),否则填 \(1\),然后将点放入 Trie 对应的子树上就行,复杂度 \(O(\sqrt W\log A)\)

\(\color{red}{\text{ABC219H}\star}\)

Tag: \(\text{费用纵算,区间dp}\)

2023/9/12

类似关路灯这种问题考虑使用区间 dp。

考虑使用类似关路灯的区间 dp 去做它,但是这是困难的因为不知道那些蜡烛还活着,记录时间又是巨大的开销。

常见但同样常忘地:费用横算(考虑每个蜡烛的时间)是困难的,考虑费用纵算(考虑每个时间的蜡烛),而纵算需要记录之后熄灭的蜡烛的个数。

我们考虑纵算每个时刻燃烧的长度,对于所有最后有长度的蜡烛,答案如下:

\[\sum A_i- T_i\times(n-i+1) \]

蜡烛熄灭后的长度算作负数,所以我们视作每个蜡烛我们一定要熄灭它,这个时候它的长度可以是负数,但是可以选或者不选(即是否将这个蜡烛加入贡献),这样最终选择的集合一定选择了所有最后长度为正的蜡烛,且没有选择长度为负的蜡烛。

于是现在我们可以选择这个蜡烛是否选,然后就可以把这个蜡烛之后还有几个蜡烛没取记录下来,取一个蜡烛的时候加入它的高度,而对于还没取的蜡烛,需要纵算他们在这段时间内燃烧的长度。

\(f_{l,r,0/1,c}\) 表示区间 \([l,r]\) 灭完,此时站在位置 \(l/r\),之后还要熄灭 \(c\) 个蜡烛的最大价值,转移就两种:选择目前站的这个位置的蜡烛(\(+A_l/r\) 用来更新 \(f_{l,r,0/1,c-1}\)),向左走灭掉蜡烛,向右走灭蜡烛,消耗的长度是距离 \(\times c\)

时间复杂度 \(O(n^3)\)


  • 费用横算和费用纵算:基于元素考虑费用和基于费用考虑元素。
  • 决策包容性的合适应用:比如最大化和可以看作每个元素是否选择,最终一定选择了所有正元素,选择负元素一定不优,这可以提前帮我们确定接下来还有多少元素。

\(\color{green}{\text{ABC244H}}\)

Tag: \(\text{凸包,李超线段树}\)

2023/9/12

垃圾题,没意思。

对于给出的 \((Ax+By)\) 将其变成 \(B(\frac A B x+y)\),然后就变成了给出若干二元组,选择最大的 \((x,y)\) 使得,\(xt+y\) 最大或最小(\(B<0\)),然后就是一个简单的带插入的,给出坐标查询若干一次函数最小值。

cdq 凸包或者直接上李超树维护下就完了,\(O(n\log n)\)

实数的话李超树是不能做到绝对正确的,但是当一个线段的长度 \(<eps\) 的时候我们可以认为它是一个点即在某个端点处值更大的一次函数的值在整个区间更大。

\(\color{red}{\text{AGC061C}\star}\)

Tag: \(\text{计数,容斥,Ad-hoc,性质}\)

2023/9/12

不会做的题。难过。流泪。好难。这咋才评 2600,少说得有个红吧,生气。

考虑以某种标准统计不同的序列数使得序列和答案一一对应。

钦定每个位置能选 \(A_i\) 就选 \(A_i\),即选 \(A_i\) 必须满足满足 \((A_i,B_i)\) 内有至少一个位置这样才能保证不重,否则一定可以移动一个 \(B_i\)\(A_i\) 得到相同的序列。

证明:

对于两个这样的序列一定本质不同,因为让某个 \(B_i\) 选择 \(A_i\) 一定会改变至少一个相对位置关系,而让某些 \(B_i\) 选择到对应的 \(A_i\),则一定存在至少一个 \(B_i\) 移动到 \(A_i\) 的过程中会跳过至少一个没有变化的位置。

这样的序列一定能够统计到所有顺序:令 \(C_i=[\text{i 选择} A_i]\),我们对于所有等价的序列 \(C_i\),我们统计最小的字典序的 \(C_i\),如果字典序不是最小的,从前往后不断地选择一个既可以选择 \(0\) 又可以选择 \(1\) 且选择了 \(1\) 的位置改成 \(0\),一定可以改到一个符合条件的串且不改变相对顺序。

所以我们需要统计 \(C\) 序列,但是基于过程统计是困难的,因为我们不知道最终哪些位置有值,所以考虑容斥:

\(L_i\) 表示第一个 \(B_j>A_i\)\(j\)\(R_i\) 表示最后一个 \(A_j<B_i\)\(j\)

那么我们钦定某个 \(C_i\) 不合法仅当:

$ C_{[L_i,i)}=0,C_{[i,R_i]}=1$

保证了中间没有出现其它值,确定了 \([L_i,R_i]\) 的值。

那么对于两个不合法位置确定的两个不合法区间,它们是不能相交的,如果出现相交那么至少有一个会合法,自行分析可以得到。即选择若干不交区间,一个区间的系数是 \(-2^{-R_i-L_i+1}\)

然后让 \(f_i\) 表示前 \(i\) 个串的答案,简单 \(\text{dp}\) 即可,复杂度线性。


  • 考虑统计字典序最大/最小的代表元可以避免算重。
  • 很多时候最终状态确定,而过程量之间相互干扰可以考虑使用容斥。

\(\color{red}{\text{AGC010E}}\)

Tag: \(\text{博弈,贪心,图论建模}\)

2023/09/18

dxm 讲的题,好智慧!这种序列交换邻项的图论建模实在是没见过。

首先考虑第二个人的 Rearrange 操作,对于第二个人来说想要最大化字典序,最终一定会被若干对不能交换的点卡住,而不能交换的点对 \((i,j)(i<j)\),考虑连边 \(i\to j\),表示 \(i\) 一定在 \(j\) 的最终顺序之前,无法交换,其它没有连边的点可以随意交换。

得到一个 DAG,那么这个 DAG 的任意一个拓扑序都是可以变成的,且仍以一个不满足拓扑序的序列都是不可以变成的,所以 Rearrange 是对这个 DAG 找到一个字典序最大的拓扑序。

那么第一个人的 Arrange 的目的就是对于这个无向图(不能交换的值连边)定向成一个 DAG,使得这个 DAG 的最大拓扑序的字典序最小。

接下来要做的事情就是贪心地,尽可能使得值较小的点在拓扑序的前面。

对于一个点的所有出边,我们肯定想要尽可能最小化这个点的最小的未访问的相邻点在拓扑序上的位置,所以肯定会选择将这个点放在尽可能前面,而让与它有连边的点的定向尽可能靠后,这样 下一步 能走到的点会尽可能小。

然后就求下最大字典序的拓扑序就行了。

\(\color{red}{\text{ABC240H}}\)

Tag: \(\text{字符串,dp优化,减少状态}\)

2023/09/19

考虑先 dp,\(f_{i,pre}\) 表示最后一段为 \([pre,i]\) 最多能分多少段,直接这样枚举下一段转移是 \(O(n^3)\) 的。

子串之间的大小关系是很不好描述的,而位置之间的关系是很好描述的,基于位置的顺序考虑是不太方便的,考虑基于子串字典序进行一个排序,然后忽略掉这个条件只计算位置关系的限制。

接下来就是对于单增的一段 \([l,r]\),选择若干段 \([l,r]\) 按顺序排列,不交,这个可以直接 dp,\(f_i\) 表示 \(i\) 结尾最长的答案,\(f_i=\min_{r_j<l_i} f_j +1\),类似 LIS,使用树状数组优化,复杂度 \(O(n^2\log n)\)

然后这个 dp 已经基本上没法优化了。看上去,不太可能低于 \(O(n^2)\) 个串的样子,但是数据范围是 \(25000\),我就陷入了如何去掉 \(\log\) 的大坑中,并没有想到观察串长等性质。

正解——观察性质:

因为是选择任意段子段,可以空出来,所以对于目前这个子段,我们肯定选的尽可能短就好。如果不要求严格单增的话肯定只会选长度为 \(1\) 的串,要求严格大于前一个的字典序,最长的情况就是前一个串是它的前缀,后一个串是,多出的是无用的,所以这个串的长度是不会大于前一个的长度 \(+1\) 的,第一个串的长度是不会大于 \(1\) 的,即使串长全部单增,其长度和至少是 \(O(maxlen^2)\) 的,所以原串中有意义的字串达到的最大长度也只有 \(O(\sqrt n)\),将所有 \(O(n\sqrt n)\) 个串拿出来做一遍上面的 dp,复杂度 \(O(n\sqrt n\log n)\),轻松通过 \(25000\)

不过我们真的要写后缀排序吗?不仅麻烦常数还大。

考虑因为每个位置为起点的 \(O(\sqrt n)\) 个串是有前后缀关系的,所以我们直接把每个点开始的长度为 \(O(\sqrt{n})\) 的串拿出来插到 Trie 里,然后 dfs 一遍即可。

歪解——同样智慧的观察:

另外一个同样智慧的观察是因为给出的串是 \(01\) 串,所以要凑出 \(c\) 个字典序严格增加的串至少需要 \(O(n\log n)\) 的长度,所以答案是 \(O(\frac n {\log n})\) 的,考虑交换 dp 值域和定义域,然后就可以做到 \(O(\frac{n^2}{\log n})\) 了!也能过。

\(\color{red}{\text{AGC004F}}\)

Tag: \(\text{转化,Ad-hoc,基环树}\)

2023/09/22

为什么同学都爆切银牌题啊?

首先考虑树怎么做:

这个要求两个点两个点颜色相同就很难受,要求颜色的同时还会改变颜色,同黑同白操作之后分别对很多东西的影响还很复杂。

有解的一个必要条件是点的个数是偶数,进一步观察是将树二分图染色后奇偶点个数相同(这里称染的颜色为奇偶,题目中的颜色为“状态”),因为一次操作一定会同时改变一个奇点和一个偶点的状态,最终要改变所有点的状态。

然后就有了一个我也不知道是怎么想出来但是巨妙的转化:我们让每个点的状态异或上它的奇偶性,初始状态是所有偶点为白(奇点被异或成黑的了),最终状态是所有偶点为黑(奇点被异或成白的),操作是选择一对相邻的奇偶点,交换它们的黑白状态。

现在问题就是树上有一些 棋子(黑点),然后每次可以将棋子移动到一个相邻的,没有棋子的位置,求到达最终状态的最少步数,充分必要条件初始状态和目标状态的棋子个数相同。

这个还是蛮典的,直接考虑每条边两侧的棋子数量和目标数量,既可以求出这条边一侧要向另一侧移动多少个棋子,这个下届是可以达到的。

考虑基环树:

环为偶环的时候,图还是二分图,我们的棋子理论和染色方式仍然适用,还是移动棋子,先跑一棵生成树,让环边的移动次数为 \(0\),然后考虑环边移动的次数对整个环上的影响,整个环的移动次数都可以增加某个值或减少某个值(整个环移动一次等于没有移动,所以可以整个移动一次或者整个往反方向移动一次以抵消掉一些原本的移动,如所有边按正方向移动一次可以通过整个环往反方向移动一次转化成环边往反方向移动一次),负值表示往反方向移动,决定这个值 \(\alpha\),那么整个环上对应边的移动次数就是 \(|x-\alpha|\),所以就是所有 \(\alpha\) 取所有 \(|x|\) 中位数时 \(\sum |x-\alpha|\) 取最小值。

环为奇环的时候,图就不是二分图了,考虑当成树做然后单独处理这条环边的贡献:操作环边相当于同时改变两个颜色相同的奇点或者偶点,等价于凭空产生两个棋子或是吃掉两个棋子,这种时候棋子的数量是可以改变的,我们可以通过初始状态棋子个数和最终状态的个数确定出这条边的操作次数,提前在这个位置放若干个棋子,或者放若干个目标就行了(这条边可以在任意时刻吃掉/产生棋子,只要两边的位置都有/没有棋子就行)。

时间复杂度线性。

\(\color{red}{\text{ARC165D}}\star\)

2023/11/1

Tag: \(\text{图论,Ad-hoc}\)

最开始甚至甚至想出了把 \(O(n^2)\) 个串看作独立的分别建点然后查是不是 DAG 的弱智想法,根本没有考虑到字串之间不是独立的。我怎么这么菜哦,笑。

考虑每个限制 \(S[A_i,B_i] < S[C_i,D_i]\),考虑其可以表示为一段 lcp 相同之后第一个不同的位置第一个串更小,这种限制是很复杂的,考虑最简洁的限制:\(S_{A_i} \leq S_{C_i}\),我们如果单纯把这些限制拿出来建出一个有向图, 这些偏序关系是 \(\leq\),所以我们不知道具体的真正的大小关系,但是我们知道 一个SCC 里面的点的值一定相同

所以我们可以单纯考虑每一条限制最弱的部分,然后一点一点推出字符的相等关系。每轮处理所有 \((A,B,C,D)\)\(S_A\leq S_C\),将关系图建出来求 SCC,如果没有产生 SCC 就合法了。否则将相同的位置用并查集缩起来,继续做。容易发现只会做 \(O(n)\) 轮,时间复杂度 \(O(nm)\)

很厉害啊!




ARC vp 记录

质量好的题先咕一会再写。

\(\text{ARC111}\)

10.30 下午做的。

三道题。没时间做D了感觉有点菜。

\(\color{green}{\text{A}}\)

唐题。我还反应了好久。 \(\lfloor \frac A B \rfloor\bmod B = \lfloor \frac {A\bmod B^2} B \rfloor\bmod B\),快速幂即可。

\(\color{green}{\text{B}}\)

简单题。经典地将正面与反面连边,因为霍尔定理,存在一组匹配仅当一个连通块有至少点数条边。不满足这个条件的连通块一定是树,可以匹配点数 \(-1\) 个。

\(\color{green}{\text{C}}\)

诈骗题。如果存在一个人拿的包裹不比自己轻且它需要给这个包裹给别人就无解。

找到置换环。对于每个置换环找到最轻的包裹,然后换一圈,一定可以的换完。因为其它人拿这的包裹都比自己轻,这个肯定也可以拿。

\(\color{blue}{\text{D}}\)

观察到 \(u \to v\) 则有 \(c_u \geq c_v\)。所以对于 \(c_u \neq c_v\),这些边的方向是确定的。 对于 \(c_u = c_v\) 的这些边它们的两个端点一定在同一个连通分量里,所以将剩余的边的连通块连成若干 SCC 即可。因为保证了有解不用跑边双,连成 SCC 的方法就直接是找一个 dfs 树,其他边全连返祖边。

\(\color{red}{\text{E}}\)

Tag: \(\text{数学,类欧}\)

如果会类欧就是简单题。

考虑一个必要条件就是区间长度 \(<D\),所以有 \(i \leq \lfloor\frac {D - 1}{B - C}\rfloor\),又因为长度 \(<D\),这样的区间至多只会含有 \(1\)\(D\) 的倍数,所以就可能含有的 \(D\) 的倍数的数量就是不合法的区间的数量,一个区间中含有的 \(D\) 的倍数数量可以用两个端点除以 \(D\) 下取整表示。

\[\sum_{i=1}^n (\lfloor\frac {A+Ci}{D}\rfloor - \lfloor\frac {A+Bi - 1}{D}\rfloor ) \]

拆开做两次类欧,复杂度 \(O(t\log n)\)

\(\color{blue}{\text{F}}\)

Tag: \(\text{巧算代价,组合,数学,矩阵快速幂}\)

一个位置上的操作总共有 \(S=\binom n 2 (2m+1)\) 种。

直接枚举一个位置 \(pos\),和查询的时间 \(t\),考虑可能的贡献,可能包含这个位置的区间数为 \(p_i=i(n-i+1)\)

首先一个位置取 \(\min\),取 \(\max\) 是巨大恶心的,考虑使用横算改纵算的办法,令 \(P(x)\) 表示答案为 \(x\) 的概率,\(Q(x)\) 表示答案大于等于 \(x\) 的概率,则有 \(\int xP(x)\ dx=\int Q(x)\),在离散意义下和积分下都是成立的,所以考虑枚举一个值 \(w\) 算答案 \(\geq w\) 的概率。

判断最终值是否 \(\geq w\)?相当于仅关心和 \(\geq w\) 的数的取 \(\max\)\(\leq w\) 的数取 \(\min\),两种操作分别有 \(p_i (m-w),p_i w\) 种,不影响它的操作有 \(G= S - p_i w\) 种。

考虑枚举这个查询前面第一个有影响的操作 \(lst\) 并钦定中间的没有影响。

那么答案为

\[\begin{aligned} \sum _{pos=1}^{n}\sum_{t=2}^{q}\sum_{lst=1}^{t-1}\sum_{w=1}^{m-1} w G^{t-lst-1}S^{lst-1+q-t} \end{aligned} \]

先把所有项都有的 \(w\) 拿出来,然后后面两个 \(\Sigma\) 拿出来一起改成枚举 \(t-lst-1\)

\[\begin{aligned} \frac{m(m-1)}{2}\sum _{pos=1}^{n}\sum_{t-lst-1=0}^{q-2}(q-1-(t-lst-1)) G^{t-lst-1}S^{q-2-(t-lst-1)} \end{aligned} \]

注意到这是带系数等比数列求和的形式,可以用手推公式,快速幂分治,矩阵乘法等做法解决,复杂度 \(O(n\log q)\)


\(\text{ARC120}\)

11.1 下午做的。感觉这场质量很高,四道题。

但是和 Eray 一起讨论着改完了。感觉自己很厉害!

\(\color{green}{\text{A}}\)

观察到第一次加完了之后所增加的 \(\max\) 就等于目前这个数了。

求出 \(\sum a_i \times i\)\(\max \times i\) 即可。

\(\color{green}{\text{B}}\)

唐题。

每条路径 R 相同仅当这个矩形的所有 \(i+j=S\)\(A_{i,j}\) 相同,因为如果出现不同一定有一步可以分叉。

\(\color{green}{\text{C}}\)

观察到一个数换来换去的话 \(a_i + i\) 是个定值。令 \(A_i = a_i + i\)\(B_i=b_i+i\),操作变成交换 \(A\) 中的相邻两个数最少次数变成 \(B\),重编号数逆序对即可,复杂度 \(O(n\log n)\)

\(\color{green}{\text{D}}\)

绝对值的包容性:\(|a-b| = \max (a - b , b - a)\)

所以我们可以任意定这 \(2n\) 个括号的符号,只需要是 \(n\)\(n\) 负即可,将前 \(n\) 大权值定成正的,然后考虑如何匹配这些括号:只要是一正一负匹配即可。 从左到右扫一遍,如果目前有没有匹配完的符号相反的括号就匹配。否则就加入没有匹配的集合。因为是 \(n\)\(n\) 负一定能匹配完,复杂度线性。

讨论了一会 \(\max\) 换成 \(\min\) 怎么做,没发现比区间 dp 更优秀做法,困难啊。

\(\color{blue}{\text{E}}\)

Tag: \(\text{性质分析,二分答案}\)

和 Eray 讨论了一会做出来了。

就是考虑一个人的策略一定是向右或向左走,碰面后调头,如果停在原地一定不优。

接下来这些人形成了一些连续的向左向右的段,大概长下面这样:

\(\texttt{>>><<<>>><<<<<>>>><<<<<}\)

使用一个经典的 trick 就是相见掉头认为是互相穿过。

于是我们考虑上面那些相邻两人相见的时间,一个形如这样 \(\texttt{>>>><}\) 的部分,左边那个极长段里相邻的人的的相见的时间,其实就是这个人遇到右边那个人之后和右边的人一起调头回来。

所以发现最晚相遇的一定是开头或者结尾或者是某个相邻但方向相反的两个人,即下方的 \(12,23,34\)

\(\texttt{>>>>> <<<< >>>> <<<}\)
\(\texttt{1\ \ \ 5\ \ \ \ 2\ 3\ \ \ \ 6 4}\)

而这种 \(23\) 相遇的时间就是分别遇到 \(5,6\) 后掉头回来的时间,等于 \(5,6\) 相遇的时间。

二分答案后维护 \(f_i\) 表示填完前 \(i\) 个人的可行性,每次填如一个形如 \(\texttt{<<<<<<>>>>>>}\) 的区间,其对应时间是这个区间左侧那个向右走的人和右侧向左走的人相遇的时间。双指针维护可行的区间,复杂度 \(O(n\log w)\)

双端队列维护一个单谷函数应该可以线性。

\(\color{blue}{\text{F}}\)

Tag: \(\text{组合,贡献计算}\)

和 Eray 讨论了一会做出来了。

对于一个位置算左右分别出现了几个是不太现实的,不能枚举一侧出现的次数,很麻烦。

胡了一个巨大卷积做法,就每个区间维护 \(4\) 个多项式 \(f_{0/1,0/1}(x)\) 表示区间两端选不选区间内选 \(x\) 个的代价和,然后分治的过程中使用卷积合并。两个 \(\log\) 感觉不是很能过。

考虑题目求的是加法,位置之间具有很强无关性,上面的卷积不仅能做加法还能做乘法。所以考虑拆开对每个位置算贡献,又因为没法算左右分别出现了几个,很烦。考虑直接左右合起来。

令长度为 \(i\) 的段,选 \(j\) 个数的方案数为 \(f(i,j)=\binom {i-j+1} j\),插板法可以求出来。

假设我们在枚举第 \(i\) 个位置的贡献,钦定其选了,其左右就不能选了,剩下 \(n-3\) 个位置。

\(\texttt{1 2 3 4 5 6 7 8 9 10 11}\)

\(\texttt{1 2 3 x i x 7 8 9 10 11}\)

剩下变成两边总共选 \(k-1\) 个,怎么算呢?

没法分开算不如直接合起来:\(n-3\) 个选 \(k-1\) 个,试图使用 \(f(n-3,k-1)\) 但是这样把两边拼起来了,少算了 \(i-2,i+2\) 同时被选的情况。所以我们要加上 \(i-2,i+2\) 同时被选的方案数。

\(\texttt{1 x o x i x o x 9 10 11}\)

这个方案数又变成了剩下两段数,两边可以随便选的方案数,试图直接使用 \(f(n-7,k-3)\) 算,但是又会漏掉 \(i-4,i+4\) 同时被选的情况,继续加上 \(f(n-11,k-5)\)……

这样一直递归直到左右一侧为空,另一侧直接使用 \(f(len,cnt)\) 计算答案即可,注意到过程中使用的全是形如 \(f(n - 3 - 4x,k - 1-2x)\) 的式子,预处理 \(f(n - 3 - 4x,k - 1-2x)\)\(x\) 上的前缀和可以做到线性。

F2 谁爱做谁做去去去。