Initializing

HMS Dreadnought

由于编辑舒适性、安全性等问题,本文不再更新。

如果需要更新的链接,联系我要。我会给的。

已部分解密文档。代号:无畏级战列舰

TEST_11

评价体系:\(\sharp\sharp\) 教育意义极大;\(\sharp\) 教育意义不错;\(\natural\) 一般;\(\flat\) 质量差。

系统自检:暂缓。

\(\sharp\) CSP-S 2025

T1 简单贪心,25min 才切,码力还不够,此乃一败。

T2 图论可能存在其他做法时坚持于思考暴力思路以外的做法,浪费时间,此乃二败。优化复杂度时没有关注瓶颈继续优化,对评测机性能估计过于激进,此乃三败。

T3 串题。对于第一眼不太可做的题,应该先发掘性质而非直接硬上,同样浪费时间。模拟赛中经常出现试图创造开放性做法,最后均没有任何收获,应当避免。

很容易想到找出 \(t_1,t_2\) 的 lcpre 和 lcsuf,分为三段 \([1,x],(x,y),[y,|t|]\)。赛时其实也画出这张图了,但没有深究而是试图哈希硬做,此乃四败。考虑 \(s_1,s_2\) 必须覆盖 \((x,y)\),故也可分为 \([1,l],(l,r),[r,|s|]\) 三段。可以发现首先 \(t_1(x,y)=s_1(l,r),t_2(x,y)=s_2(l,r)\),其次 \(s_1[1,l],s_2[1,l]\) 分别是 \(t_1[1,x],t_2[1,x]\) 的后缀,\(s_1[r,|s|],s_2[r,|s|]\) 分别是 \(t_1[y,|t|],t_2[y,|t|]\) 的前缀。同时由于 \(t[1,x],t[y,|t|]\)\(t_1,t_2\) 的 lc{pre,suf},故 \(s[1,l],s[r,|s|]\)\(s_1,s_2\) 的 lc{pre,suf}!

这个结论就非常炸裂了。首先说明了一个 \((s_1,s_2)\) 不可能匹配两次,至多贡献 \(1\)。其次三个部分一定是对齐的,这给统计答案带来了极大便利,可以用 ACAM 直接解决了:搞个 \(s'\gets s[1,x]+\texttt{\#}+s_1(x,y)+s_2(x,y)+\texttt{\#}+s[y,|s|]\)\(t'\) 同理,然后直接跑多模匹配即可。

字符串的匹配常常引出美妙的性质,如果未加观察往往导致难度剧增。很多时候都是问题没有限制清楚导致感觉根本不可做。

T4 poly 显然需要观察性质。使用计数 dp 或组合数,有待提高,此乃五败。

做题 / 比赛策略;graph 和 string 的性质观察;dp / counting 能力。

\(\sharp\) PNR #7

T1 双重和式。排序完直接钦定答案计算即可。想和写太慢了。

T2 条件排列数数。很快意识到没办法直接做,遂考虑容斥,非常正确。容斥完变成有 \(t\) 个位置满足 \(|b_i-b_{i+1}|\),不会了。因为发现可能有多个满足条件的位置连成一段,没法直接用组合数算。所以为啥不用 dp 做?有点糖。

我们将 \(b\) 划分为若干公差为 \(k\) 的等差数列组成的连续段,对连续段 dp。先对所有 \(a_i\) 排序,找出所有极长等差数列连续段,接下来我们要把 \(a\) 中的连续段拆开放进 \(b\),统计方案数。设 \(f(i,j)\) 表示已经考虑了 \(a\) 中的前 \(i\) 个连续段,划分出了 \(j\) 段的方案数。dp 时连续段之间无顺序之分,故最后要乘上 \(j!\)。考虑处理出一个连续段拆开的方案数,发现当长度 \(\ge 2\) 时可以翻转,需要特殊处理。设 \(g(i,j,1/2)\) 表示将一个长度为 \(i\) 的段划分成 \(j\) 个,且第 \(j\) 个长度 \(=1/\ge 2\) 的方案数。

\[\begin{aligned} g(i,j,1)&\xleftarrow{+}g(i-1,j-1,*)\\ g(i,j,2)&\xleftarrow{+}2g(i-1,j,1)+g(i-1,j,2)\\ f(i,j)&\xleftarrow{+}f(i-1,j-l)\times g(len,l,*) \end{aligned} \]

计数需要加强。还有硬做 link

T3 树上等价类计数,纯粹的性质发掘。

由于黑白点是对称的,不妨设 \(w\ge b\)。考虑不变的量,当一个点必须为白时才可能把黑点堵住。设删去点 \(i\) 后产生连通块大小最大值为 \(max_i\),一个点任意时刻必须为白的充要条件为 \(max_i<w\)

若有点必须为白时,即 \(\min max_i<w\) 时,删去所有必须为白的点会得到一些连通块。其中大小大于等于 \(b\) 的连通块的数量即为方案数。否则答案为 \(1\)\(2\)

统计答案需要以重心为根分讨子树大小情况,感觉这题太 Ad-hoc 了,不太 NOIP 风格。有点浪费时间。

T4 冒泡排序相关。感觉作为 NOIP T4 不太合适了?

dp / counting 能力;性质观察。

\(\sharp\) 2025-11-22 校内模拟赛

By hhoppitree。这下吃上好的了。两题不会,那扎了。

T1 分讨一下可以发现被包含的先消,其他情况无所谓。然后被包含的一定 \(r\) 更小,所以从左往右贪,能消就消就做完了。要用 bit 维护距离不太优美了。

T2 考虑操作的含义,直接把连通块变成完全图了。所以直接启发式合并 + dsu 即可。启发式合并可以同时维护所有儿子编号,这是相对于 dsu 的强点,不过还是要用 dsu 维护连通块的根。

前两题比较常规了,复习了一下比较典的。

T3 赛时惯性思维了,直接考虑缩点完变成 dag,然后不会了。如果从编号区间角度考虑的话,不仅对于一个确定的区间难以快速求出是否合法,而且区间数量还很多完全无法统计。dag 角度更不用说了,相当于 dag 可达性,总之各方面坏完了。一切的原因是往所有可达点方面想了。

根据题目的定义,很自然地会快速转化题意为 dag 可达性。然而这种先入为主的转化不一定是好的,反而可能将问题。本质上是忽略了题目给出的组合对象隐含条件,必然没有前途。

T4 还没补。

TEST_21

【未解密】

TEST_30

归档

AtCoder-arc165_f Make Adjacent

出现两次的排列,邻项交换使得奇偶位置上相同,最小化次数基础上最小化字典序。求操作后的排列。

考虑任意两个数之间的影响。对于 \([l_x,r_x]\)\([l_y,r_y]\) 不交或包含的情况,移动操作不会影响另一个数移动的距离。当且仅当 \(l_x<l_y<r_x<r_y\) 时会相互影响。此时可以发现先动 \(x\) 更优。

考虑拍到平面上。\(l_x<l_y<r_x<r_y\) 的条件太严了,考虑 \(r_x<l_y\) 时先动 \(x\) 必然不劣。于是条件化为若 \(l_x<l_y\land r_x<r_y\) 时先动 \(x\)。操作即为每次删掉一个点,且其左下没有点。可以建图连边跑拓扑序解决。

边数是 \(O(n^2)\) 的,要优化建图(sgt 或 cdq)。从大到小扫描 \(l\),线段树维护 \(r\),则连出去的边是一段后缀。

扫描 \(l\) 时会新加入 \(r\),需要使用可持久化规避上个时刻对当前 \(r\) 连边。

AtCoder-abc209_e Shiritori

考虑建出博弈图。如果将字符串视为点,转移视为边则不好建图,建虚点不方便搜。点边互换,可以将字符串视为头三个字符向后三个字符的转移,则点数为 \(|\Sigma|^3\),边数为 \(n\)

对于平局的情况,可以在反图上 bfs。考虑到如果一个点必胜,那么必然有一个确定是必败的后继可以访问到自己。同理如果一个点必败,则所有后继都确定是必胜。故非平局情况都会被搜到,没搜到默认是平局即可。

CodeForces-888G Xor-MST

考虑 kruskal 的过程,每次选出两个异或和最小的点连接。可以发现 trie 树上选出的两个点的 lca 深度一定在不断变小,因为 lcp 越来越短异或值越来越大。

所以可以在 trie 上从下往上考虑,保证当前子树内的点全部连通,当有两个孩子时找出两个分别在左右子树内的点,使得异或和最小。暴力枚举左子树内叶子,搜右子树中对应候选答案即可。

每个点只会被其祖先搜到,时间复杂度 \(O(n\log V)\)

Boruvka 不太会。

AtCoder-abc345_f Many Lamps

太智慧了。考虑答案上界,必然是小于等于连通块大小的最大偶数,且下界以下的都可以构造达到。因为可以直接翻转新加入的点到未被点亮的点(若存在)之间的链上的边的状态。类似于二分图匹配增广。

但这样不太好做,考虑依次加入一条边后构造答案。若加入的边是非树边,则可以通过翻转其对应的链上边的状态达到选择该边的效果,故所有非树边都是不必要的。只考虑树边即可。

对树进行构造,从下往上,若当前点未被选择,那么选择他和他父亲之间的边。这样构造最多只有根未被点亮。

CodeForces-843D Dynamic Shortest Path

首先跑一遍最短路,考虑如何处理修改。

重新算最短路不太现实,考虑到边权的增量只有 \(1\),总增量最多 \(10^6\),考虑计算新最短路相较于旧最短路的增量。

使用势能解决,建一张新图 \(G'\),边权为 \(w-(dis_v-dis_u)\)。注意 \(w\) 是修改后的边权。边权可以拆成两部分,一部分是修改产生的贡献,另一部分是走修改前边权相对于最短路增加的量。dijkstra 中的堆可以用桶代替,少一只 \(\log\),变成和值域相关。

时间复杂度 \(O(m\log m+\sum c)\)

洛谷-P7737 庆典

首先考虑缩点,不影响连通性。缩点后为 dag,尽量转成树方便处理。题目中给的条件 \(x\leadsto z,y\leadsto z\)\(x\leadsto y\lor y\leadsto x\)。说明对于 \(v\) 的多个入边 \((u_1,v),(u_2,v),\dots,(u_d,v)\),只需保留拓扑序最大的 \(u\) 连的 \((u,v)\),其他 \(u_*\) 均可以到达 \(u\),连通性依然不变。

处理完每个点最多一条入边,变成了一颗叶向树。对于新加入的边,将其端点和起点 \(s\) 终点 \(t\) 提出来建立虚树,求 \(s\leadsto u\leadsto t\)\(u\) 的数量。分配给虚树点权和边权,求合法点边权之和即可。

洛谷-P9697 Canvas

后面的染色会覆盖前面的,正难则反,变成一次染色后不会再变。

\((2,2)\) 显然要先做,\((1,1)\) 最后做。对于 \((1,2)\),需要确定它们的顺序。对于一个 \((u,v)\),若它选了,则所有 \((v,w)\) 都可以选。这样的传递关系不难想到建图,直接连 \((u,v)\)。可能存在环,所以考虑缩点。取一个点为 \(1\) 后,所有其可达点都可取到 \(2\),考虑直接取所有入度为 \(0\) 的分量最优。注意有些点被 \((2,2)\) 钦定为 \(2\),不会损失。

CodeForces-1903F Babysitting

考虑答案有单调性,故二分答案。考虑怎么判定一个 \(mid\) 是否合法。将点覆盖的条件转化为 2-SAT

  • 对于一条边 \((u,v)\)\(u\lor v\)\(\neg u\to v,\neg v\to u\)
  • 对于一个点 \(u\),选 \(u\) 则所有满足 \(|u-v|<mid\)\(v\) 都不能选,\(u\to \neg v\)

第二种线段树优化建图即可。

CodeForces-1253F Cheap Robot

考虑到电量可能导致状态数过多,故考查电量 \(x\) 的取值范围,显然有 \(x\le c-dis_u\)。设 \(dis_u\) 表示 \(u\) 到最近充电站距离,当 \(x<dis_u\) 时无法到达任何一个充电站,也无法到达终点,直接报废。当 \(x\ge dis_u\) 时,可以去对应充电站加满后回来,\(x\gets c-dis_u\)

故一个点只有两种电量:\(x<dis_u\),不合法;\(x=c-dis_u\)。考虑通过一条边需满足的条件 \((c-dis_u)-w\ge dis_v\),前提是 \(u\) 合法。显然充电站都合法,故条件即为 \(dis_u+dis_v+w\le c\)。回答查询时直接最小化 \(a\to b\) 路径上边权最大值即可。

洛谷-P3588 沙漠 Desert

真难绷。考虑将大小关系用连边表达,跑个拓扑排序即可。

对于每个询问 \(k_i\) 个关键点向剩下区间中的点连边,但是连的边是三次方级别的,建立虚点降到两次方级别。考虑到 \(\sum k\le 3\times 10^5\),关键点分割出的连续段最多 \(O(\sum k)\) 个,线段树优化建图就可以降到 1log。

洛谷-P5025 炸弹

考虑直接连边表示引爆情况,连的边是区间,线段树优化建图。缩点后变成 DAG 可达性。

可达点是一段区间,拓扑排序时直接维护即可。

神秘 \(O(n)\) 做法不太通用?link

大意是用单调栈维护可达关系,因为其有传递性。

洛谷-P6880 奥运公交 / Olympic Bus

神秘最短路树。枚举每一条边尝试翻转。\(1\leadsto n,n\leadsto 1\) 分开考虑。

如果边在最短路树上,重跑最短路,一共 \(n-1\) 条边每次 \(O(n^2)\)

如果边不在最短路树上,若新最短路经过该边,则取 \(dis(1,v)+w+dis(u,n)\)。反之仍为原最短路。

翻转时要加上翻转的代价。

洛谷-P5590 赛车游戏

构造边权是困难的,考虑构造最短路。类似于势能,边权必须为 \(dis_u-dis_v\),对其进行限制即可 \(1\le dis_u-dis_v\le 9\)

洛谷-P5304 旅行者

任意一对关键点之间的最短路。

考虑二进制分组,两个关键点编号必然有一位不同,所以肯定会统计到所有最短路。

另一种神秘做法是直接钦定每条边更新。

CodeForces-1163F Indecisive Taxi Fee

无向图删边最短路。

考虑最短路径(链)。分讨四种情况(其中三种是平凡的)。若将最短路径上的边权改大,此时只有两种决策:仍走最短路或不走修改的边。若不走修改的边,在 sgt 上维护不走某条边的最短路径。每有一条非链边,在 sgt 上做一次区间取 min,值是经过这条非链边的最短路。查询单点查即可。

AtCoder-arc199_c Circular Tree Embedding

考虑简化题目条件方便处理。不难发现可以根据 \(P_1\) 重标号,使 \(P_1=[1,\dots,n]\)。条件是根据排列把边拍在环上,可以将环整体旋转,使 \(P_{*,1}=1\)

断环为链,不难发现环的限制就是对于权值排列 \(P\),使得子树内权值为连续段。同时由于 \(P_1\) 的限制,编号一定也是一个区间。直接区间 dp 即可。

\(f(l,r)\) 表示编号在 \([l,r]\) 之间的点组成的树的方案数。枚举根节点 \(i\),将 \([l,i-1]\)\([i+1,r]\) 任意划分,dp 值乘起来。可以记一个 \(g(l,r)\) 表示 \([l,r]\) 之间的点组成森林的方案数辅助转移。转移 \(f(l,r)\) 时需要判断一下 \([l,r]\)\(P_{2\sim m}\) 中是否合法,即 \(P_{*,[l,r]}\) 是否在值域上是连续段。

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

洛谷-P6622 信号传递

首先考虑拆贡献,对于 \(x\le y\)\(w(x\to y)=a_y-a_x,w(y\to x)=ka_x+ka_y\)。这里 \(a_x,a_y\) 是排列后的位置。

故可以将一个点 \(v\) 的贡献表示为 \(\left(\sum_{u\le v}e_{u,v}+\sum_{v\le u}ke_{u,v}+\sum_{v\le w}-e_{v,w}+\sum_{w\le v}ke_{v,w}\right)a_v\)\(u\to v\to w\))。

从左到右 dp 每个位置,设 \(f(S)\) 表示 \(1\sim |S|\) 的位置上已经填了 \(S\) 中元素,最小代价。新加入一个元素 \(i\in S\) 时,考虑产生的贡献 \(g(i,S\setminus\{i\})\times (a_i=|S|)\)。根据前文整理可得 \(g(i,S)=\sum_{j\in S}(e_{j,i}+ke_{i,j})+\sum_{j\notin S}(ke_{j,i}-e_{i,j})\)。递推可求。

时空复杂度 \(O(m2^m)\),空间需要卡常。

CodeForces-2151E Limited Edition Shop

\(f(i,j)\) 表示选到 \(a_i\)\(b_j\),考虑题目中的限制。

一个物品只有两种状态,被 A 选或不被 A 选(被 B 选)。当 A 新选择一个物品 \(a_i\) 时,必须保证 \(a_i\) 之前的物品都被选了,且 \(b_{b^{-1}(a(i))}\) 没有被选。\(a_i\) 之前的物品,被 A 选的显然合法,被 B 选的可能会影响到 \(b_{b^{-1}(a(i))}\),如果出现在 \(b_{b^{-1}(a(i))}\) 之后,则 \(b_{b^{-1}(a(i))}\) 必须被选,不合法。

所以如果选 \(a_i\),设 \(a_i\) 前面没有被 A 选的数在 \(b\) 中出现位置的最大值为 \(p\),则必须满足 \(p<b^{-1}_{a(i)}\)。不选的话没有限制。

\[\begin{aligned} f(i,j)&\xleftarrow{\max}f(i-1,j)+v_i&(j<b^{-1}_{a(i)})\\ f(i,\max(j,b^{-1}_{a(i)}))&\xleftarrow{\max}f(i-1,j) \end{aligned} \]

线段树优化即可。

\[\begin{aligned} t[1,b^{-1}_{a(i)}]&\xleftarrow{+}v_i&(v_i>0)\\ t[b^{-1}_{a(i)}]&\xleftarrow{=}\max t[1,b^{-1}_{a(i)}] \end{aligned} \]

CodeForces-888F Connecting Vertices

区间 dp。考虑设 \(f(i,j)\) 表示 \([i,j]\) 全部连通且 \(i,j\) 之间有连边的方案数。这样一来就不可能出现向 \([i,j]\) 内部连边。但是这样不能直接转移。设 \(g(i,j)\) 表示 \([i,j]\) 内随意连通的方案数。

\[\begin{aligned} g(i,j)&\xleftarrow{+}g(i,k)\times g(k+1,j)\\ g(i,j)&\xleftarrow{+}f(i,k)\times g(k,j)\\ f(i,j)&\xleftarrow{+}g(i,k)\times g(k+1,j) \end{aligned} \]

洛谷-P6563 一直在你身旁

考虑区间 dp:已知答案在 \([i,j]\) 内,确定答案的最小代价。转移显然枚举猜测点

\[f(i,j)\gets\min_k\{\max(f(i,k),f(k+1,j))+a_k\} \]

\(\min\) 的决策点没啥规律,考虑拆 \(\max\)。设 \(g(i,j)\) 为第一个 \(k\) 使得 \(f(i,k)>f(k+1,j)\),递推可求。

接下来分类讨论决策点 \(k\) 位置。正序枚举 \(j\) 倒序枚举 \(i\),当 \(k<g(i,j)\) 时,\(f(i,j)\gets\min_k\{f(k+1,j)+a_k\}\)\(g(i,j)\) 向左移动时维护单调队列即可。

\(k\ge g(i,j)\) 时,\(f(i,j)\gets\min_k\{f(i,k)+a_k\}\),关于 \(k\) 单调递增,取 \(k=g(i,j)\) 最优。

洛谷-P4229 某位歌姬的故事

有操作的。限制相当于

\[\forall i\in [l,r],a_i\le w\land\exists i\in [l,r],a_i=w \]

考虑对于两个限制,若他们无交则好处理。若有交,假设两个限制 \(w\) 不同,则 \(w\) 更大的那个可以删去相交的部分。这样以来,所有 \(w\) 不同的限制均不相交,方便处理了许多。

考虑所有限制 \(w\) 相等的情况。我们将区间离散化,变成若干个基本元素,给元素染黑白两色,保证每个区间至少有一个黑色。

\(f_i\) 表示第 \(i\) 个染成黑色(?)

洛谷-P4516 潜入行动

计数 dp,考虑对象为若干关键点,同时关键点无法覆盖自己,故设计状态为 \(f(i,j,0/1,0/1)\) 表示 \(i\) 为根子树内 \(j\) 个关键点,\(i\) 是否是关键点、\(i\) 是否被覆盖。

\[\begin{aligned} f(u,i,0,0)&\xleftarrow{+}f(u,j,0,0)\times f(v,i-j,0,1)\\ f(u,i,0,1)&\xleftarrow{+}f(u,j,0,1)\times f(v,i-j,*,1)+f(u,j,0,0)\times f(v,i-j,1,1)\\ f(u,i,1,0)&\xleftarrow{+}f(u,j,1,0)\times f(v,i-j,0,*)\\ f(u,i,1,1)&\xleftarrow{+}f(u,j,1,1)\times f(v,i-j,*,*)+f(u,j,1,0)\times f(v,i-1,1,*) \end{aligned} \]

树形背包即可。

洛谷-P5853 Tree Depth P

首先转化题意,对于 \((u,v)\),其对 \(u\) 的贡献为有 \(k\) 个逆序对的排列中满足 \(v\)\(u\) 的父亲的数量。\(v\)\(u\) 的祖先当且仅当 \(a_v<a_u\)\(u,v\) 之间没有小于 \(a_v\) 的数。

考虑对于每一个 \(u\),计算每一个 \(v\) 的贡献。

现在有一个 \((u,v)\) 的限制条件,若 \(u<v\),我们考虑按 \(u\to v,u-1\to 1,v+1\to n\) 的顺序确定每一个数。这样一来,限制条件就变成了填 \(v\) 的时候必须填最小值,造成 \(v-u\) 的贡献。也就是必须撤销第 \(v-u+1\) 轮的所有贡献,并只转移 \(v-u\)

同理若 \(v<u\),则按 \(u\to v,v-1\to 1,u+1\to n\) 的顺序,同样撤销第 \(u-v+1\) 轮,只转移 \(0\)

我们先做一次 dp,由于 \(v-u\) 相等的 \((u,v)\) 需要撤销的相同,故考虑合并处理,\(f(n-1,k-\max(v-u,0))\) 即为贡献。

洛谷-P1777 帮助

\(f(i,j,k,S)\) 表示前 \(i\) 个数删了 \(j\) 个,最后一个没删的是 \(k\),所有选了的数是 \(S\)

\[\begin{aligned} f(i,j,a_i,S)&\xleftarrow{\min}f(i-1,j,k,S\setminus\{a_i\})+[l=a_i]\\ f(i,j,k,S)&\xleftarrow{\min}f(i-1,j-1,k,S)\\ ans&\xleftarrow{\min}f(n,m,*,S)+|U\setminus S| \end{aligned} \]

洛谷-P5933 串珠子

\(f_S,g_S,h_S\) 表示 \(S\) 中点组成任意 / 连通 / 不连通图的方案数。

随意显然是好做的

\[f_S\gets\prod_{i,j\in S}(e_{i,j}+1) \]

考虑不连通的情况。考虑随意取 \(k\in S\),考虑 \(k\) 所在的连通块 \(T\) 的情况。\(T\) 显然要连通,\(S\setminus T\) 则随便连

\[h_S\gets\sum_{k\in T\subsetneq S}g_S\times f_{S\setminus T}\\ g_S\gets f_S-h_S \]

答案即为 \(g_U\)

AT_arc184_d [ARC184D] Erase Balls 2D

直接对剩余球的集合计数比较难做,考虑对选择的球的集合计数。

但是这样不能建立双射,考虑增加限制:选择的球的集合必须是极大的,也即选择任意一个集合外的球都会导致有球被删。这样显然就一一对应了,反之可以取并集推出矛盾。

将球按照 \(x\) 坐标升序排序,那么选出的球必然满足 \(y\) 坐标降序,否则会相互删除。考虑怎么判定一个选球集合是否合法。可以取出所有 \(x,y\) 坐标在任意相邻两个球之间的球(即不会被删除的球),判断对于任意一个球是否都满足她偏序了另一个球。

\(f_i\) 表示考虑到第 \(i\) 个球且选她的方案数。枚举前驱 \(j\)\(O(n)\) 判定合法即可。可以添加 \((0,n+1),(n+1,0)\) 两个球方便转移和统计答案。时间复杂度 \(O(n^3)\)

AT_abc279_g [ABC279G] At Most 2 Colors

考虑如果已经保证了一个前缀 \(i\) 合法,能在后面加什么颜色 \(a_i\)。相当于是删除了上一个连续段的第一个元素 \(a_{i-m}\),并加上了最后一个元素 \(a_i\)。如果想要出现 \([i-m,i-1]\) 之外的第三种颜色,必须保证 \([i-m+1,i-1]\) 均为同色。所以我们将同色后缀的长度记入状态。

\(f(i,j)\) 表示已经保证了前缀 \(i\) 合法,\([j,i]\) 是极长同色连续段,染色的方案数。

\[\begin{aligned} f(i,j)&\gets f(i-1,j)&(j<i)\\ f(i,i)&\gets \sum_{\mathclap{j=i-k+2}}^{i-1}f(i-1,j)+\sum_{j=1}^{i-k+1}(V-1)f(i-1,j) \end{aligned} \]

第一维可以直接滚掉,前缀和优化即可。

AT_arc186_a [ARC186A] Underclued

01 矩阵,行和列和,考虑二分图。

\(a_{i,j}=1\),则 \(L_i\to R_j\),反之 \(R_j\to L_i\)。这样点的度数就刻画了行和、列和。考虑如果两个矩阵相似,那么她们对应的图一定度数对应相等,此时我们将两个图的边取出来,取对称差删去共有的边,剩下的图度数仍然相等,边取消定向后也相等。可以发现剩下的一定是一堆环。

如果一条边不在任何一个环上,那么她就是固定的。考虑统计环边的可能数量,设 \(f(i,j,k)\) 表示已经考虑左部点 \(i\) 个右部点 \(j\) 个,造出 \(k\) 条环边是否可行。每次添加 \((i',j',k'=i'\times j')\) 个左右部点和边,转移即可。

AT_arc186_d [ARC186D] Polish Mania

合法序列显然可以转化成树上节点按 dfs 序的儿子个数。合法当且仅当和为 \(n-1\) 且对于每一个前缀和都大于等于前缀长度,即

\[\sum_{i=1}^n a_i=n-1\\ \forall 1\le i<n,\sum_{j=1}^ia_j\ge i \]

第一行意思就是树的边数为 \(n-1\),第二行就是对于每一个真前缀包含的点组成的树要有剩下的边,留给后面挂儿子。

考虑如何计数。对序列做一遍前缀和转化成格路计数,序列 \(a\) 对应的路径在 \(x=i\) 上升 \(a_{i+1}\),不能碰到 \(y=x-1\)

组合数计算即可。对于字典序的限制有经典做法,枚举第一个小于 \(a_i\) 的位置,钦定前面的相等,计算方案数累加即可。特殊处理一下全部相等的情况即可。

https://atcoder.jp/contests/arc186/submissions/64168476

AT_arc187_c [ARC187C] 1 Loop Bubble Sort

前缀最大值将序列划分为若干个区间,一次冒泡排序本质上是将前缀最大值从区间开头移到末尾。我们发现前缀最大值是重要的,将其记入状态。设 \(f(i,j)\) 表示 \([1,i]\)\(P\) 的前缀最大值为 \(j\) 的方案数。考虑在 \(P_i\) 处填什么,即分讨是否是前缀最大值。

\(P_i=j\),则 \(P_i\) 将向后移动,那么 \(Q\)\(P_i\) 必须在 \(i\) 之后或没有出现。同时 \([1,i-1]\) 的前缀最大值 \(k\) 将被放在 \(i-1\) 处,故 \(k\) 需要满足 \(Q_{i-1}=k\) 或没有出现。对于满足条件的 \(k<j\)\(f_{i-1,k}\gets f_{i,j}\)

\(P_i<j\),则 \(P_i\) 将向前移动,

  • \(Q_{i-1}\ne -1\),则 \(P_i=Q_{i-1}\),前面一定不会填过 \(Q_{i-1}\),转移不会重。
  • \(Q_{i-1}=-1\),则(?)

洛谷-P9209 不灭「不死鸟之尾」

先考虑一个固定宽度 \(len\) 的连续段,停在哪里最合适。\(W_i-R_i\cdot l-L_i\cdot r=W_i-R_i\cdot len-(L_i-R_i)l\),所以要尽可能最大化 \(len,(L_i-R_i)l\)。所以每次只可能停放在两边。

CodeForces-1661D Progressions Covering

从后往前贪,当前数不满足条件就一直加到满足,这样前面也会加到。

洛谷-P9378 物理实验

字典序 / 次幂贪心。

从大到小考虑每个元素,尽可能加入答案。

加入答案后测试是否合法即可。

AtCoder-abc254_h Multiply or Divide by 2

构造操作方案使得两多重集相等,最终一定两两匹配。可以发现操作 \(A\) 中一个元素 \(x\gets 2x\),等价于 \(B\) 中一个元素 \(y\gets y/2\),前提是 \(y\) 是偶数。

每次取出两个集合中的最大值,将大的除以二,相等则抵消。

操作本质是对 \(x\)(的前缀)的移位,所以考虑中间相遇。

洛谷-P5749 排列鞋子

考虑两双鞋子如何操作。如果区间相离或包含,操作先后顺序不会有任何影响。考虑 \(l_1\le l_2\le r_1\le r_2\),此时肯定要先动 \(l_1,r_1\),即将 \(r_1\) 向左移动。

从左到右贪即可,用 bit 维护所需操作次数。

洛谷-P5665 划分

重要的贪心结论:尽可能多分段,对于每一段,和越小越好。(?)

设最优决策点为 \(f_i\),相当于我们宣称对于所有合法决策点 \(j,\,s_j-s_{f(j)}\le s_i-s_j\)\(f_i=\max j\)

移项,得 \(2s_j-s_{f(j)}\le s_i\)。设 \(v_j=2s_j-s_{f(j)}\),则可以用单调队列优化。每次将队首 \(v_*\le s_i\) 的出队,最后一个出队的即为最优决策点,转移即可。\(v_i\) 加入时弹掉 \(v_*\ge v_i\) 的队尾元素即可。

洛谷-P7482 不条理狂诗曲

分治,考虑怎么处理 \(l\le i\le mid<j\le r\) 的情况。

左右分别做一边 dp,左边做后缀,钦定 \(mid\) 随意 / 不选 \(fl_i,gl_i\),右边做前缀钦定 \(mid+1\)\(fr_j,gr_j\)

对于 \([l,r]\),贡献为 \(\max(fl_i+gr_j,gl_i+fr_j)\)。枚举每一个 \(i\),分讨大小关系 \(fl_i-gl_i>fr_j-gr_j\)\(j\)\(fr_j-gr_j\) 排序,二分即可找到 \(j\) 的分界点。算一下 \(gr_j\) 的前缀和,\(fr_j\) 的后缀和即可。

Bonus:dp 可以设 \(f,g\) 分别表示钦定最后一个数任意或不选的最大值,\(f'\gets\max(f,g+a_i),g'\gets f\)。把 \(f\) 提出来 \(f'\gets f+\max(0,g+a_i-f),g'\gets f\)。所以每加入一个数 \(f\) 的增加量和 \(f'-g'\) 均为 \(\max(0,a_i-(f-g))\)。故只需要维护 \(f-g\) 的值即可递推。

CodeForces-1716E Swap and Maximum Block

观察操作本质含义,类似于线段树上某一层都交换左右儿子。可以发现本质只有 \(2^n\) 种状态。

考虑分治从下往上解决,儿子的状态只有 \(2^{d-1}\) 种,枚举对应状态合并。复杂度 \(O(n2^n+q)\)

洛谷-P6406 Norma

分治不是纯赤石???

考虑枚举右端点 \(j\),维护每个左端点 \(i\) 的答案。后缀最大值的形式想到单调栈。考虑 \(j\) 的贡献

\[\sum_i(j-i+1)s^{\max}_is^{\min}_i=(j+1)\sum_is^{\max}_is^{\min}_i-\sum_is^{\max}_is^{\min}_ii \]

然后这玩意是可以用 sgt 维护的,维护 \(s^{\max}_i,s^{\min}_i,s^{\max}_ii,s^{\min}_ii,s^{\max}_is^{\min}_i,s^{\max}_is^{\min}_ii\) 的和即可。

洛谷-P9361 Contests

图论建模复杂度无法承受。注意到 \(m\) 比较小,对于一个点的所有可达点可以表示为 \(m\) 个排名。

考虑倍增求出可达点,从大到小尝试跳 \(2^*\),若不超过就跳。

CodeForces-1511G Chips on a Board

求区间 nim 和

\[\bigoplus_{a_i\in [l,r]}(a_i-l) \]

没有带修,考虑倍增。发现 nim 和形式有

\(f(i,j)\) 表示 \([l,r]=[i,i+2^j-1]\) 的 nim 和。发现转移的时候因为倍增的优美性质贡献很好算

\[f(i,j)\gets f(i,j-1)\oplus f(i+2^{j-1},j-1)\oplus [g(i+2^{j-1},i+2^j-1)\bmod 2=1]\times 2^{j-1} \]

其中 \(g(l,r)\) 表示 \([l,r]\) 的出现次数 \(\sum_i[l\le a_i\le r]\)。回答查询一样合并即可。

CodeForces-1523H Hopping Around the Array

多次询问而不带修,\(k\) 很小,考虑倍增。

\(f(i,j,k)\) 表示从 \(i\) 开始跳 \(2^j\) 步,可以删 \(k\) 个点,能跳到的最优位置。我们称一个点能跳到的位置越大越优,这样下一步有更多选择。

初始化需要使用 ds 维护能跳到的最远位置求出 \(f(i,0,k)\)。预处理的时候直接枚举划分 \(k\) 次删除给两个儿子取 \(\max\) 即可。查询同理,开 \(k\) 个点表示已经删了 \(k\) 个点能到达的最优点。类似背包转移即可。

CodeForces-1707E Replace

观察到函数的输入是区间,状态数太多。类似 NOIP 2024 T4 地,考虑将 \(f(l,r)\) 拆成若干 \(f(i,i+1)\)。发现

\[f(l,r)=\bigcup_{i=l}^{r-1}f(i,i+1) \]

很好理解,画个折线图即可证明。可以发现陪域是连续区间,所以 \(f^k\) 也满足上式,因为一定是若干基本区间 \(f(i,i+1)\) 首尾相连并成的。

考虑倍增处理 \(f^{2^j}(i,i+1)\),初始化边界是简单的,预处理时要使用 rmq 合并 \(j-1\) 层的区间。查询也倍增 + rmq 合并即可。

P7880 [Ynoi2006] rldcot

https://www.luogu.com.cn/article/rmdqa1b8

最朴素的办法是将 \(O(n^2)\) 个点对 \((i,j)\)\(dep_{\operatorname{LCA}(i,j)}\) 拍到平面上做矩形数颜色。但点太多了。

考虑两个点对 \((a,b),(c,d)\) 如果满足 \(\operatorname{LCA}(a,b)=\operatorname{LCA}(c,d)\)\(a<c<d<b\),那么 \((c,d)\) 一定是没用的。所以我们希望找到 polylog 个点,包含所有有效点对进行维护。

考虑在 lca 处统计,寻找一个点对 \((u,v)\) 有效的必要条件。显然 \(u,v\) 应该在 lca 的不同子树内,不难想到在 dsu on tree 时每次添加一个子树,直接遍历该子树内点并在当前大子树内查找前驱后继 \(v,v'\),即可找到 \(O(n\log n)\) 个点对,包含所有有效点对。

处理出所有点后考虑扫描线。从右往左扫,扫到 \(x\) 时维护一个前驱 \(pre_c\) 表示所有颜色为 \(c\)\(i\ge x\)\(\min j\),区间查询等价于查询 \(i\ge l\)\(pre_c\le r\) 的颜色个数。维护一个 \(pre\) 的权值树状数组即可。

P11364 [NOIP2024] 树上查询

考虑经典的虚树结论

\[dep_{\operatorname{LCA}([l,r])}=\min_{l\le i<r} dep_{\operatorname{LCA}(i,i+1)} \]

那么,问题变成有若干元素 \(f(i)=dep_{\operatorname{LCA}(i,i+1)}\),每次区间询问滑动窗口最小值的最大值。

考虑枚举最小值,钦定 \(f(i)\) 为最小值时的极大区间 \([x_i,y_i]\) 满足 \(\min f([x_i,y_i])=f(i)\)。这样对于任意区间 \([l',r']\subseteq [x_i,y_i]\),其区间最小值均为 \(f(i)\)。(感觉跟笛卡尔树有点关系。)

此时转化为由若干个区间,每次询问求与 \([l,r]\) 交大小超过 \(k\) 的区间中 \(f\) 的最大值。拍到平面上,可以发现条件是一个挖掉右下角一个三角形的四分之一平面,割开分别对 \(r\)\(k\) 扫描线即可。

\[x\le l-k+1\land y\ge r\\ y-x+1\ge k\land l+k-1\le y\le r \]

P9119 [春季测试 2023] 圣诞树

不太懂四边形不等式,但是大概看出来了不应该相交,瞎猜了一下性质一定是左右两边交替扩展(不然这题没法做),对了。性质可以用三角形两边之和大于第三边证。

断环为链,直接倍长序列 dp 即可。

P1315 [NOIP 2011 提高组] 观光公交

感觉有点乱,dp 肯定比较难做。考虑每条边对答案的贡献。贪心怎么想不清楚!

P5021 [NOIP 2018 提高组] 赛道修建

二分答案,然后 dfs 从下往上贪心,满足长度要求就扔掉开一个新的链,尽可能多造链。

需要将若干子树的链合并。

P5017 [NOIP 2018 普及组] 摆渡车

不太会斜优。

P2322 [HNOI2006] 最短母串问题

建出 AC 自动机,然后在第 \(i\) 个模式串的节点上赋 \(2^{i-1}\) 的权,然后直接在 AC 自动机上 bfs,每次并上搜到的点的权,直到 \(U=2^n-1\) 即可。状态数量是 \(2^n\sum |s_i|\),算上出边复杂度 \(O(2^nn|s||\Sigma|)\)

P9809 [SHOI2006] 作业 Homework

还以为是操作分块什么的。模数可变看上去不太可做,但是取模的性质很好,直接考虑阈值分值。

\(mod\le B\) 时,可以每次添加数时直接枚举模数预处理答案。复杂度 \(O(B)\)

\(mod\ge B\) 时,需要利用商值域为 \(n/mod\) 的性质,直接枚举商,考虑怎么快速求出 \(k\cdot mod\) 的后继(大于等于的第一个存在的数),可以直接用 set 维护,复杂度 \(O(n/B\log n)\),取 \(B=\sqrt{n\log n}\) 总复杂度为 \(O(n\sqrt{n\log n})\)。如果倒序处理,用 dsu 维护后缀,总复杂度可以做到 \(O(n\sqrt{n\alpha})\),值域分块平衡复杂度可以做到 \(O(n\sqrt{n})\)

dsu 是可以维护后继的,不过只支持删元素。

P9478 [NOI2023] 方格染色

斜线只有 \(5\) 条,对于每条直接暴力判是否相交,容斥掉重复的贡献即可。

剩下直接扫描线。

P8868 [NOIP2022] 比赛

怎么这么牛。这东西在线一眼不可做,考虑离线下来。一开始的想法是钦定最大值,然后弄些支配点对出来扫描线,结果发现好像不太能支配。

应该直接对 \(r\) 从小到大扫描线,然后所有子区间最大值就变成所有前缀的后缀最大值,就是后缀最大值的历史和。单调栈的时候推平一下区间就可以了。

P4216 [SCOI2015] 情报传递

不是很难?很套路的转化 \(beg<qid-C\),然后数个数。这个在线硬做得用主席树,3log 糖糖的。可以离线下来,然后按 \(beg,qid-C\) 排序,依次处理每个操作,容易发现后面的修改对前面的查询没有影响,然后就解决了时间这维的偏序变成树上单点加链查,dfn + bit 随便切。

以为普通线段树就能做数个数直接开题解了,结果发现得用主席树。离线不太清除是不是自己想到的了/ll。

P5024 [NOIP 2018 提高组] 保卫王国

全集权值和 = 最大独立集 + 最小点覆盖。

其实直接做也是可以的,弄个矩阵然后数剖 + 线段树维护就可以了。

AT_arc084_b [ABC077D] Small Multiple

考虑最后的答案 \(ans\)\(k\) 的倍数,因此 \(ans\equiv 0\pmod k\),同时满足 \(\operatorname{popcount}(ans)\) 最小。

考虑维护模 \(k\) 意义下不同数的最小 popcount,可以发现每个数只需要通过 \(+1\)\(\times 10\) 即可达到,直接连边 \((i,(i+1)\bmod k),(i,10k\bmod k)\),计算 \(1\leadsto 0\) 的最短路即可。

AT_agc056_c [AGC056C] 01 Balanced

出现次数相同,不难想到弄成折线前缀和,差分约束。限制是好做的 \((l-1,r,0),(r,l-1,0)\),对于任意两个相邻的位置,限制它们的差必须为 \(\pm 1\),连 \((i,i-1,1),(i-1,i,1)\)。这就比较难搞了,因为只能限制 \(|dis_i-dis_{i-1}|\le 1\) 而不能限制其不等于 \(0\)

但是!我们发现连 \(0\) 边两侧的点奇偶性相同,而 \(1\) 边两侧的点奇偶性不同。这样一来,\(|dis_i-dis_{i-1}|\ne 0\),完美解决问题。最后上个 01bfs 即可。

P4001 [ICPC-Beijing 2006] 狼抓兔子

平面图最小割,对偶图直接对每个「块」建个点连边即可。

CF1765I Infinite Chess

无法直接 bfs。\(x\) 的范围很大,考虑将 \(y\) 相同的一些点(同一列)的连续段合并,减少状态数。

对于一个棋子,竖着攻击会直接报废一整列,横着攻击会将连续段切开,斜着攻击和马也会切开连续段,当成散点处理。由于王会斜着走,但是可以发现必要的斜走最多 \(8\) 步,故连续段左右要预留 \(8\) 格。

于是对于每列,遍历其割开的位置,将连续段合并即可。时间复杂度 \(O(kn\log n)\)\(k\) 为巨大常数。

P2149 [SDOI2009] Elaxia的路线

以前就见过的牛牛题,recall by mspaint。

问题等价与求最短路 DAG 的交上的最长链,但是注意交是无向的。

TEST_499122207

CF1707E CF1523H P8945 AT_arc186_c AT_arc187_c P4229 P1399 P2081

P1315 P5017 P2322 P9478 P8868 P4216 P5024 AT_arc084_b AT_agc056_c CF1765I

TEST_31

P11363 P9871 P3573 P3188

P9923 P4099 P7606

P4216 P4069 P1600 P5069 P8868

P3825 P11210 AT_arc153_d

P1263 P3825

USACO G / P?

P8867

TEST_41

【未解密】

posted @ 2025-11-06 17:56  Po7ed  阅读(45)  评论(0)    收藏  举报