ZR 26 NOI 内训

ZR 26 NOI 内训

5.20 杂题选讲

题相对简单一些,当然我说的是相对后面的题。

QOJ5402 术树数

首先如果 \(k=2\) 那么这是经典问题,用线性基维护即可。那么我们可以考虑一个 \(k\) 进制线性基的状物来求解。

具体来讲就是我们只要求它是一个上三角矩阵,所以在一行上可以辗转相除直到有一个向量在最高位上为 \(0\)。但是这里和二进制线性基不同的是,同一个向量加很多次是会有额外的贡献的;为了处理这个信息,我们可以考虑一个经典结论:对于当前向量的最高位 \(a\),我们加 \(\frac{k}{\gcd(a,k)}\) 次之后向量的最高位不变,所以我们实际上还需要插入这个向量的 \(\frac{k}{\gcd(k,a)}\) 倍来处理这个情况。

查询的时候就是朴素的枚举然后尽可能减小最高位。这里为了方便起见可以在插入向量的时候将最高位 \(a\) 改为 \(\gcd(k,a)\),这样查询最小值的时候可以直接用除法来计算,不用再写 exgcd 了。

P15939 [JOI Final 2026] 传奇团子吃家

感受一下会有一个这样的贪心:我们枚举每一段,记 \(s\) 表示当前的最大子段和,\(ans\) 为答案,那么我们枚举 \(i\in [l,r]\),每一次做如下操作:

  • \(s\leftarrow \max(0,s\pm a_i)\)
  • \(ans\leftarrow ans+\lfloor\frac{s}{k} \rfloor\)
  • \(s\leftarrow s\bmod k\)

然后考虑这个 \(\max\) 很烦,如果全程没有和 \(0\) 取过 \(\max\) 的话答案就是总和除以 \(k\)。所以考虑对每个位置找出其下一次取 \(\max\) 操作的位置,然后倍增跳段即可。复杂度 \(O(n\log n)\)

P15944 [JOI Final 2026] 传送机 2

这个题的结论有点意思。考虑将所有不交的区间之间连边,则题目的要求是最长链 \(\le K\),我们知道最长链等于最小反链覆盖。考虑最小反链是什么,发现其实就是一组区间两两不交,那么他们会有一个共同的交。

那么对于这 \(K\) 个交,我们选出其中的任意一个点作为代表点不会有影响,那么两个代表点之间的区间全部都要删掉。所以设 \(f_{i,j}\) 表示第 \(j\) 个交的代表点为 \(i\) 的最小代价。转移是容易的,观察发现转移的代价函数满足四边形不等式,于是 dp 对 \(K\) 有凸性,wqs 二分后线段树优化 dp 即可。

P9344 [JOIST 2023] 水羊羹 2

先来考虑一下最优的划分方案的形式,依然是经典的先找必要然后证充分。注意到一个谷长度至少为 \(1\),那么此时作为峰的大段的一个必要条件是 \(s_{l,r}>\max(a_{l-1},a_{r+1})\)。接下来说明这是充分的:考虑两个合法段 \([l_1,r_1],[l_2,r_2]\),如果 \(a_{r_1+1}> a_{l_2-1}\),那么将 \([l_1,r_1]\) 延伸到 \(l_2-2\) 显然是合法的,反过来一样的。

所以对于一个点 \(x\),我们假设他是最后一个大段的右端点,我们令 \(nxt_x\) 表示下一个合法大段的最小右端点。那么我们查询相当于暴力跳 \(nxt_i\) 直到跳出区间,用分块维护即可做到 \(O(\sqrt n)\),注意分讨一下开头结尾有没有谷。

最后是修改,注意到大段长度是 \(O(\log V)\) 的,显然每次扩展时总和扩倍。所以说有 \(nxt_i-i\le \log V\),并且我们还知道每次修改只会影响 \(O(\log V)\)\(nxt\)。所以暴力修改,复杂度 \(O(n\log^2 V +n\sqrt n)\)

5.21 模拟赛

\(72+17+40=129\),rk \(28\)

为什么你们有 pretest 还能挂分的?

T1 矩阵的秩

直接做有一个经典 dp 是 \(O(n^2)\) 的,写出它的生成函数是 \(F(x)=\prod\limits_{i=0}^{m-1} \frac{1}{1-2^ix}\)。我们考虑 \(F(2x)=\prod\limits_{i=1}^{m} \frac{1}{1-2^i x}\),所以有 \(F(2x)(1-2x)^m=F(x)(1-x)\),然后就可以解出第 \(n\) 项系数了。

T2 偶数图

\(k=2\) 的部分分提示我们想到欧拉回路,并且我们知道如果没有偶数长度的限制可以直接建虚点跑欧拉回路。所以问题在于这个偶数长度的限制。注意到图的总边数也是偶数,这提示我们将相邻的两条边配对并缩起来,这样显然不改变度数奇偶性,然后再对这个图跑一遍欧拉回路,展开之后自然路径长度为偶数。复杂度线性。

5.22 模拟赛

\(16+100+55=171\),rk \(21\)

为什么 T3 这么卡常啊?

T1 线性规划

注意到一个结论是 \(\prod x \le P\),否则根据抽屉原理存在两组另外分 \(x\) 满足他们的结果同余,两者作差之后可以得到两个对原先 \(x\) 的调整,这个调整中一定有一个是更优的解。

于是考虑钦定 \(x_0>x_1>x_2>x_3\),分组可以发现 \(x_1\)\((x_2,x_3)\) 的枚举量分别都是 \(O(\sqrt p)\) 的。所以考虑 meet in the middle 合并一下。为了方便合并可以现将 \(x_0\) 的系数改成 \(1\),复杂度 \(O(\sqrt p\log p)\)

当然你会问如果顺序不是这个怎么办,很简单,我们暴力 \(4!\) 枚举一下即可。

5.25 杂题选讲

怎么这么难 \ll

P11696 七影蝶

太阴了。考虑拆位处理,对于第 \(k\) 位,我们将所有数在模 \(2^k\) 意义下进行考虑。发现对于每个 \(a_i\)\((a_i+x)\) 在第 \(k\) 位上为 \(1\)\(x\) 是至多两个区间内的 \(x\),也就是说这两个区间内的 \(x\) 需要加一。

然后发现当 \(k\to k+1\) 的时候,我们会将原本的序列复制一份接在后面,然后再进行区间修改。那么此时的操作可以概括为区间复制、区间修改、查询区间最值,可持久化线段树维护一下即可,复杂度是 \(O(n\log^2 V)\) 的,无法通过。

考虑一下整体的结构,我们发现每层会修改 \(O(n)\) 个区间,这些区间也就将这个序列划分成了 \(O(n)\) 段。可以证明的是,如果区间 \([l,r]\) 在第 \(k\) 层被划分为同一段,那么在更高的层上 \([l,r]\) 一定也在同一段。于是对于一段来说,我们可以直接求出这一段内的最大值然后将他们合并,这样每一层上都只会保保留 \(O(n)\) 个区间的信息。

最后考虑查询,由于最后我们只有 \(O(n)\) 个区间,所以 \([l,r]\) 会被划分为若干整段和一些散段,散段需要向下递归查询。这样的话我们每一层都需要维护 rmq,需要写 \(O(n)-O(1)\) rmq 才能做到单老哥。一个简单的处理方法是我们将所有查询端点也扔进每一层的区间作为端点,这样每一层维护 \(O(n+q)\) 个区间,查询的时候一定是若干整段,写一个 rmq 即可,复杂度 \(O((n+q)\log V)\)。注意要在每一层的时候精细实现,用基数 / 归并排序和双指针做到严格线性才能通过。

QOJ6509 Not Another Range Query Problem

感觉很神秘的一个做法。考虑如果查询 \([1,r]\) 怎么做,容易发现我们可以钦定每一次是先删连续段最左边的数,求出每个数被删掉的时间,然后做二维数点。求时间可以用单调栈或者链表维护。

然后发现查询 \([l,r]\) 的时候这么做最开头的连续段会炸,并且我们不好调整。脑洞一下,我们钦定每一次先删连续段最右边的数,用原来求出来的 \([1,r]\) 的答案减去这么做求出来的 \([1,l-1]\) 的答案,会发现这就是正解。证明感性理解一下吧。

P13336 Shifting Paths

\(n\le 40\) 是一个很经典的数据范围,我们考虑折半的思想。如果单纯的将状态拆成两个的话会发现毫无作用,所以我们需要的是只记录一边的状态,另一边提前预处理。

\(n\) 开始在反图上 BFS 求出每个点的 \(dis\),将 \(dis\) 靠前的若干个作为集合 \(B\),剩下的作为集合 \(A\)。我们考虑在 \(B\) 里面暴力跳,然后预处理 \(A\) 的信息。设 \(f_{u,S}\) 表示当我们在 \(A\) 中的点 \(u\)\(A\) 中所有点状态为 \(S\) 时,第一次跳到 \(B\) 的步数及状态,可以记忆化搜索来转移,复杂度 \(O(2^{|A|}|A|)\)

接下来我们考虑在 \(B\) 里面暴力跳的复杂度。显然我们在 \(B\) 中的状态也可以描述为 \((u,S)\)。可以证明,我们不会走到相同的 \(S\) 两次。考虑这是为什么,对于一个状态 \((u,S)\),如果我们再次回到 \(S\) 那么必然要求每个点都走过了他的两个出边,对于 \(u\) 来说,两个出边中至少有一个的 \(dis\) 比他自己小,如此递归下去我们一定能走到 \(n\)。于是在 \(B\) 中暴力跳的复杂度就是 \(O(2^{|B|})\)

P13695 theseus

给边赋权可以看做给边定向。首先把从 \(T\) 开始 BFS,然后将图分层。依次考虑每条边,很显然对于两个端点不同层的边,我们直接定向即可,问题只在于同层之间的连边。

我们发现额外限制 \(C\)\(O(\log n)\) 级别的,所以我们在同层跳的时候肯定要有一个什么东西扩倍了。考虑启发式合并,我们从深到浅考虑所有边:

  • 如果 \(dep_u>dep_v\),定向 \((u,v)\),并令 \(siz_v\leftarrow siz_v+siz_u,siz_u=0\)
  • 如果 \(dep_u=dep_v\),钦定 \(siz_u<siz_v\),定向 \((u,v)\),并令 \(siz_v\leftarrow siz_v+siz_u,siz_u=0\)

这样的话我们的步数只会多出 \(O(\log n)\),这样就满足限制了。但是这个时候有一个问题是我们实际上并不知道 \(u\) 合并到了哪个 \(v\) 上,我们希望合并的时候这个 \(v\) 满足一些特殊条件。考虑将所有边 \((u,v)(u<v)\) 按照 \(u\) 从大到小、\(v\) 从大到小排序,容易发现这样的话 \(u\) 合并到 \(v\) 的时候,\(v\) 一定是 \(u\) 编号最大的出边。

QOJ8820 Exchanging Kubic 2

先考虑差分原序列,这样一次操作相当于找到 \(\le x\) 的以及 \(>x\) 的第一个差分不为 \(0\) 的位置将其 \(-1\)。将一次操作写成三元组 \((l_i,x_i,r_i)\),很显然我们现在的条件太强了,考虑进行一定弱化。

你会发现我们不必找到第一个差分不为 \(0\) 的位置,因为如果找到了更远的位置那么显然是不优的。所以我们的条件实际上只有 \(l_i,r_i\) 这两个位置上的差分值不为 \(0\)。进一步的,\(l_i,r_i\) 之间实际上没有什么关系,所以可以进一步拆成两个二元组 \((l_i,x_i)\)\((x_i,r_i)\),要求每次操作时 \(l_i\)\(r_i\) 的差分值不为 \(0\)

然后我们就可以得到一个简单的贪心:枚举 \(i\),先将 \(\ge i\) 的所有 \(x\)\(l\) 依次填上,如果填满了的话就依次填所有 \(<i\)\(x\)\(r\)

根据这个贪心我们可以设计一个 dp:设 \(f_{i,j,k}\) 表示当前到集合 \(S_i\)\(a_i=j\)\(k\) 记录当前贪心填到的最远的 \(x\),如果 \(\le n\) 表示填满了 \(x\in [1,k]\)\(l\),否则表示填满了所有的 \(l\) 以及 \(x\in [1,k-n]\)\(r\)。注意到我们的 \(k\) 是有上下界的,如果 \(k<i\),那么 \((k,i]\) 这些 \(x\)\(l\) 永远不可能再填了,令 \(k=i\) 即可;如果 \(k>n+i-1\),说明剩下的差分值已经填不下了,需要计入极差里。所以 \(k\) 的范围是 \([i,n+i-1]\)。然后前缀和优化一下就行了,复杂度 \(O(nm(n+m))\)

CF2061I Kevin and Nevik

首先我们有一个很简单的 dp:设 \(f_{i,j}\) 表示前 \(i\) 场比赛赢了 \(j\) 场所需最少时间。转移是 \(O(n^2)\) 的,但是这个 dp 较难以用传统方式优化出来。

仔细观察发现,如果我们要转移 \(f_{l,*}\)\(f_{r,*}\),当 \(|j-(l-j)|>r-l\) 时,中间的所有 \(a_i=-1\) 的位置要么全赢要么全输,而剩下的比赛如果要选一定贪心从小往大选取。容易发现此时的转移代价函数是凸的,决策单调性优化这一部分转移。

然后考虑此时剩下的部分怎么办,容易发现此时 \(f_{l,j}\) 还没有转移的是一段连续区间,且区间长度是 \(O(r-l)\) 的。考虑分治下去,转移 \(f_l\to f_{mid}\to f_{r}\),此时对于 \(f_l\),它只有 \(O(r-l)\) 个位置需要转移;对于 \(f_{mid}\),它同样只会接收到 \(O(r-l)\) 个值。所以在每次分治的时候,我们需要转移的位置都只有 \(O(len)\) 个,每次决策单调性需要带一个老哥,所以总复杂度 \(O(n\log^2 n)\)

代码比较构式,主要是转移的边界比较难处理。

P7783 Gracemeria Patrol

这种翻转的题目可以考虑用线性代数来刻画。设 \(f_i\) 表示翻转完 \(1\sim i\)\(i\) 行的向量,\(a_i\) 表示原先的向量。那么假如已知 \(f_{i-1}\),我们操作 \((i,j)\) 当且仅当 \(f_{i-1,j}=1\)。构造一个矩阵 \(A\) 来刻画转移,我们有 \(f_i=f_{i-1}A\oplus a_i\)。于是可以得到一个公式:

\[f_k=f_1\oplus \bigoplus_{i=2}^k a_i A^{k-i} \]

首先我们知道 \(f_n=0\),然后可以解出 \(f_1\) 的值。那么知道 \(f_1\) 后就简单了,先判断 \(f_1\) 是否可以唯一由 \(a_1\) 得到,然后输出 \(f_{k-1}\)\(1\) 的个数即可。改成区间查询也很简单,每次求一下差分然后算一算就行了。

最后一个问题是求解过程中需要求出 \(A\) 矩阵的逆,打表可以发现只有当 \(m\equiv 2\pmod 3\)\(A\) 没有逆,此时输出 -1 即可。

5.26 模拟赛

\(100+10+5=115\),rk \(18\)

这个 T1 是来 cos recollector 的,一车 \(O(n^3)\) 都过了。

T2 比较

我们把问题拆成两步,先确定所有 \(c_i\) 排序后的结果的情况数,然后再还原排序前的答案。

排序后的 \(c_i\) 的相邻关系只有两种,所以可以二进制直接状压。我们还要求和为 \(m\),所以还需要做一个背包。对于这种物品数很小的背包,可以考虑将 \(c_i\) 写成 \(\log m\) 位二进制,然后在这个 \(\log m\times n\) 的表上轮廓线 dp。设 \(f_{x,y,S,0/1,j}\) 表示轮廓线跑到坐标 \((x,y)\),当前所有 \(c_i\) 的相邻关系为 \(S\)\((x,y)\) 这一位是 \(0/1\),当前位的和需要为 \(j\) 的方案数。这一部分是 \(O(2^n n^2\log m)\) 的。

接下来我们还原排序前的答案,设 \(g_{i,S,T,j}\) 表示当前确定了前 \(i\) 个数,前 \(i\) 个数的相邻关系为 \(S\),没有确定的 \(n-i\) 个数的相邻关系为 \(T\)\(c_i\) 在没有确定的 \(n-i\) 个数中排名为 \(j\) 的方案数。这个的状态数是 \(\sum\limits_{i=1}^n 3^i 2^{n-i} (n-i+1)\) 的,实际上就是 \(O(3^n)\) 的。所以总复杂度为 \(O(2^n n^2\log m+3^n)\)

T3 博弈

首先考虑写一个暴力,我们考虑求出每个状态的 SG 值,但是难点在于这个题我们会回溯,回溯后的状态我们是不知道的。考虑直接将回溯后的所有 SG 值记录下来,设 \(f_{u,S}\) 表示当前在点 \(u\)\(u\) 回溯后的所有状态的 SG 值构成的集合为 \(S\)。转移倒序枚举出边,每次令 \(S\leftarrow S \cup \{f_{v,S}\}\)。最后返回 \(\text{mex}(S)\) 即可。

当然上面描述的是对于白点的转移,现在我们考虑所有点都是白点怎么做。发现一个性质是 \(f_{u,S}\notin S\),因此每次改变 \(S\) 的时候当前数一定没有在 \(S\) 中出现过。而我们最后求的其实是 \(f_{u,\{0\}}\),所以实际上我们不关心 \(\text{mex}\) 具体是几,我们只需要关心他是 \(S\) 补集中的第几小数即可完成转移。倒序枚举出边,维护当前补集中最小的还没有出现的数即可。

然后考虑有黑点怎么办,由于黑点的转移是固定的,因此每个黑点状态只有唯一的后继,于是黑点的 \(\text{mex}\) 只有可能是 \(0,1\)。虽然他不满足上面的性质,但是我们可以直接暴力状压当前的补集中有没有出现 \(0,1\),然后再转移即可。这样可以做到线性的复杂度。

5.28 杂题选讲

QOJ17430 Unique Sheet

做一些必要的极端情况讨论,发现一个值如果只出现一次,那么它所在行列都不能删除。考虑这样的数至少有 \(2(n-k)^2-n^2=(n-2k)^2-2k^2\) 个,那么这代表着我们总共只有 \(O(k)\) 个行列可以被删除,于是可以直接暴搜出所有可能情况判断即可。判断的时候需要用异或哈希做到 \(O(k^2)\) 即可通过。

QOJ17165 Four Sages Around an Oak Tree

首先我们接受的信息只有 \(4\times 3\times 3=36\) 种可能,对于每种情况我们决定一个返回值,那么总的决策组数量为 \(3^{36}\)。理论上暴搜加剪枝可以较快的剪出一种合法的方案。

这里提供一种构造:考虑令 \(a=b+d,c=b-d\),如果有相同的话直接返回。否则说明 \(a=b+d\pm 1,c=b-d\pm 1\),此时令 \(b=\frac{a+c}2,d=\frac{a-c}2\),那么必定有一个数的 \(\pm 1\) 被抵消,至少会有一个是对的。

CF643F Bear and Juice

我们考虑从信息个数的角度去考虑。考虑 \(k\) 天后我们得到的信息有什么:每个熊是否睡觉了,如果睡觉了是在第几天睡的觉。枚举总共的信息量,可以得到答案的上界:

\[\sum_{i=0}^{min(p,n-1)} \binom{n}{i}\times k^i \]

接下来相信你猜到要干嘛了,我们证明这就是答案。很简单,考虑令第 \(i\) 种方案为第 \(i\) 个桶里有酒。对于一只熊的某一天来说,如果他在第 \(i\) 种方案中睡着了,就让他在这一天喝第 \(i\) 桶即可。

然后求组合数的时候暴力约分,复杂度不会超过 \(O(p^3 \log p)\)

5.29 模拟赛

\(50+3+0=53\),rk \(17\)

有些炸裂了,你们海亮的题怎么这么难 \kel

T1 基础计数练习题

容易发现 \(m=10^9\) 是无用的,因为剥掉叶子以后就只有 \(O(n)\) 个了。然后有很多可以做到 \(O(n^5)\)\(O(n^4)\) 的办法,但是本质相同且没有优化前途。考虑到这个题我们只关心每个连通块 \(\max\) 之积,剩下的我们并不关心,于是想到从大到小枚举每个点来处理这个 \(\max\)

现在要处理的就是两种转移:新建一个基环树或者将当前点合并到原先基环树上。首先刻画一下基环树,很显然我们给每个点钦定恰好一个出边即可。那么新建一个基环树我们直接将这个点能到达的所有点加入,合并直接加入一条链连接到先前的基环树即可。但是这个时候我们可能会加入一些比当前点小的点,延迟钦定一下即可。

所以设 \(f_{i,j,k}\) 表示当前考虑到第 \(i\) 个点,左部点加入了 \(j\) 个,右部点加入了 \(k\) 个的方案数。转移分三种情况,一个是延迟钦定的编号,一个是新建基环树,一个是合并到原来的基环树上。直接做可以得到一个本质不同的 \(O(n^4)\) 做法,前缀和优化即可做到 \(O(n^3)\)

T2 回文

设多项式项数为 \(d\),那么多项式回文的条件可以写成 \(f(x)=f(x^{-1})x^{d-1}\)。于是对于每个限制 \((x_i,y_i)\),我们将 \((x_{i}^{-1},\frac{y_i}{x_i^{d-1}})\) 也加入限制。拉插出一个多项式 \(f(x)\),这个多项式对于所有 \(x_i\) 都满足上面的限制,最后为了使其回文,我们构造 \(g(x)=\frac{f(x)+f(x^{-1})x^{d-1}}2\) 即可。

但是这个多项式不一定满足 \(g(0)\ne 0\),同时在上面的过程中我们也没有考虑 \(x_i=0\) 的限制。考虑给 \(f(x)\) 加上一个多项式调整 \(f(0)\) 的值来保证这些条件。很显然,构造 \(h(x)=\prod (x-x_i)\) 可以在不影响其他限制的情况下修改 \(f(0)\) 的值,所以给 \(f(x)\) 加上若干倍的 \(h(x)\) 使其满足条件即可。

最后的问题是我们的 \(d\) 是不确定的,暴力枚举的复杂度似乎会炸。但事实上我们可以 \(O(n)\) 判断对于当前的 \(d\) 是否存在矛盾的条件,矛盾我们就不用跑这个 \(d\) 了。事实上最后只有 \(O(1)\)\(d\) 可以进行构造,单次构造复杂度 \(O(n^2)\),总复杂度 \(O(nd+n^2)\)

T3 nodgd 的游戏

太阴了。整体大概分成三部分:观察出充足的性质写出一个暴力,简化暴力的形式,然后数据结构优化。先特判掉 1000...0000...0 两个 corner case。

体会一下这个过程,由于 \(0\) 角色可以把后面的 \(1\) 拉过来,所以它们实际上也可以打出伤害;而打不出伤害的只有每一回合最开头的 \(0\)。因此对于我方来说,希望 \(0\) 尽快跑到开头,对面则相反。

  • 性质一:我方决策是将最靠前的 \(1\) 扔到后面,对方决策是将最靠后的 \(1\) 扔到前面。

接下来手玩一下上述过程可以得到:

  • 性质二:我方刚操作完后的队列和一回合后的队列相对顺序一致。

因此我们可以得到一个暴力做法,先求出所有数均为 \(1\) 的答案,然后考虑求出丢失的伤害;每一轮将第一个元素后的第一个 \(1\) 放到最后,然后删掉第一个元素,如果第一个元素为 \(0\) 则丢失串长的伤害。至此我们得到了一个基础的暴力。

接下来优化,考虑维护一个队列状物来实现上述过程,如果当前元素为 \(0\) 那么一定作为第一个元素被删掉;如果当前元素为 \(1\),需要讨论一下当前队列中有无元素,如果有那么它会被队头的元素扔到末位,我们就不用管他,然后弹出队头;否则说明它是第一个元素,加入队列。实际上就是维护一个队列大小 \(sz\) 以及当前串长 \(len\),每一次操作:

  • 如果 \(a_i=0\)\(ans\leftarrow ans-len,len\leftarrow len-1,sz\leftarrow sz+1\)
  • 如果 \(a_i=1\)
    • 如果 \(sz\ne 0\)\(sz\leftarrow sz-1\)
    • 否则 \(len\leftarrow len-1,sz\leftarrow sz+1\)

到这可以分块维护做到 \(O(q\sqrt n)\),但是常数太大可能过不去。通过观察实际上我们可以发现,由于 \(sz\) 是连续变化的,因此如果我们将 0 看做 \(+1\),将 \(1\) 看做 \(-1\),实际上 \(sz=0\) 的位置就是所有奇数位上的前缀和的前缀最小值,\(sz\) 就可以丢掉了。

有了这个简化就做完了,上一个单侧递归线段树维护 \(ans\)\(len\) 的变化即可,复杂度 \(O(q\log^2 n)\)

5.30 杂题选讲

草了,题写不完了。

CF2124G Maximise Sum

先观察一下,容易发现 \(i\) 一定取前缀最小值,否则的话只会修改滚木。然后进一步发现 \(j\) 一定取得是后缀最大值,这样一定更优。然后精细讨论一下 \(i,j\) 的对数,令 \(pre\) 表示前缀最小值,当 \(a_i+a_j\ge pre_{i-1}\) 时,这样的 \(a_j\) 我们实际上只需要保留一个 \(j\) 最大的即可;否则对于 \(a_i+a_j< pre_{i-1}\),容易发现 \(a_{i}+a_j\in [pre_i,pre_{i-1})\),显然这些数的总和是 \(O(n)\) 的。

于是可以分析出 \((i,j)\) 对的数量是 \(O(n)\) 的。剩下的部分就比较简单了,每次相当于我们要修改两个位置的值,然后查询整体代价。无脑上单侧递归可以做到 \(O(n\log^2 n)\),实际上稍微讨论一下就可以做到 \(O(n\log n)\)。我们找到修改后的 \(a_i'\) 后第一个比它小的数 \(a_p\),以及区间 \((i,j)\) 中的最小值 \(a_q\)。然后 \([1,i),[i,p),[q,j),[j,n]\) 的贡献全部都是容易的,并且 \([p,q)\) 的贡献也就是一个后缀和,于是就做完了。

CF1887E Good Colorings

有一个经典的等价转化是网格图和二分图,也就是将网格的行和列看成二分图的左部点和右部点,然后每个格子对应一条边。这个题我们直接转成二分图,此时每条边有颜色。由于存在 \(2n\) 条边,所以一定可以找出一个偶环。

考虑在这个偶环上面二分,每次我们在中间连一条边将环劈成两半。由于当前环的颜色互不相同,因此这两个环中也一定有一个环的颜色互不相同,递归下去求解即可。操作次数 \(O(\log n)\)

6.1 杂题选讲

儿童节活动:宝宝题选讲。

AT_codefestival_2015_final_h 焼肉の達人

首先注意到两个包含的区间不会同时存在,否则被包含的区间就是滚木。然后进一步发现一个点被覆盖三次也是滚木,只保留覆盖这个点左端点最小和右端点最大的区间一定不劣。

于是认为每个点只会被覆盖 \(0,1,2\) 次,到这里其实已经可以 dp 了,不过我们有一个巧妙的做法。考虑用二倍总长度减去损失的代价,容易发现一个点被覆盖 \(0\)\(2\) 次时代价为 \(2\),否则代价为 \(1\)。然后我们进行如下建图:

  • 对于每个区间 \([l,r]\),连边 \((l,r,r-l+1)\)。这代表了覆盖 \(1\) 次的区间。
  • 对于每个 \(i\),连边 \((i,i+1,2)\)\((i+1,i,0)\)。这分别代表了覆盖 \(0\) 次和覆盖 \(2\) 次的区间。

然后跑一遍最短路就完了,复杂度 \(O(n\log n)\)

P11346 [KTSC 2023 R2] 会议室 2

首先删除改成加入,然后发现我们对于若干连通块一定是一个一个往里加的,否则不优;并且我们一定先加入较大连通块。于是我们只需要考虑单个连通块的情况,最后乘一个阶乘就完了。然后考虑对于一个连通块怎么做,容易发现我们一定是保证每一个时刻都只有一个连通块才能最优。

考虑怎么刻画加线段的过程。在加入线段的时候,有一些线段加入后连通块的并会变大,把这些线段称作关键线段。我们考虑每一条关键线段插入后连通块的并 \([l_1,r_1],\cdots,[l_k,r_k]\),那么考虑一个非关键线段 \([l,r]\),找到第一个 \(i\) 满足 \([l,r]\subseteq [l_i,r_i]\),这条线段只能在这个关键线段插入后插入。建一棵树表示插入顺序,把所有关键线段依次连成链,然后把非关键线段挂到它对应的关键线段上,这样求出树的拓扑序就是答案。

分析一下,对于第 \(i\) 条关键线段,它子树之外的线段个数应当是所有被 \([l_{i-1},r_{i-1}]\) 包含的线段个数,令 \(w_{l,r}\) 表示 \([l,r]\) 包含的线段个数,简单推一下可以推出来答案就是 \(\frac{(m-1)!}{\prod_{i=1}^{k-1}(m-w_{l_i,r_i})}\)。然后直接 dp 可以做到 \(O(n^3)\),前缀和优化可以做到 \(O(n^2)\)

6.2 模拟赛

\(100+70+8=178\),rk \(15\)

注意到这场模拟赛的供题方是西安搞笑椅子,后面忘了。总之搬了三个疑似一车人见过的简单题,随了几组暴力能过的数据,放了一个错的题解。不知道是何意味。

T1 保险丝

注意到 \(deg=2\) 的点几乎没有用,将所有二度点缩掉。此时剩下的点的度数 \(\ge 3\),注意到此时所有邻域大小之和的上界可以由完全二叉树取到,为 \(O(n\log n)\),所以我们这个时候跑暴力就行了。注意要精细处理一下被缩掉的二度点贡献,复杂度 \(O(n\log n)\)

T2 矩阵

存在 \(O(2^{\frac{\min(n,m)}2})\) 做法,但是不是预期中的正解。考虑网络流,我们把网格画出来,每个格子当做有权值。接下来我们对于 \(i+j\) 为奇数的格子,把它左下角和右上角的格点之间连边,否则把它左上角和右下角的格点之间连边,权值都是当前格子的权值。

这样注意到对于所有不能同时出现的格子,它们对应的那条边一定有一个交点。所以我们只需要求出这个图的最大权匹配即可。注意到这个图也是二分图,跑一遍二分图最大权匹配即可。复杂度 \(O((nm)^3)\)。感觉这个建模还挺有意思的。

6.3 杂题选讲

CF908H New Year and Boolean Bridges

由于任意两点 \(u, v\) 之间至少有一个可达另一个,所以缩点后剩下的 DAG 一定是一条链。那么先考虑答案是什么,容易发现答案是 \(n-1+cnt\),其中 \(cnt\) 为大小 \(>1\) 的 SCC 个数。

然后翻译一下限制,与限制就是两个元素必须在同一个 SCC 内,异或限制就是两个元素必须在不同的 SCC,或限制本质就是滚木。先把所有与限制合并,有矛盾就输出无解。此时所有大小为 \(1\) 的 SCC 肯定不动,然后我们需要将剩下的大小 \(>1\) 的连通块尽可能合并,使得 \(cnt\) 最小。

仔细考虑一下会发现此时剩下的连通块只有至多 \(m=\frac{n}{2}=23\) 个,因此考虑状压。首先枚举出 \(f_S\) 表示集合 \(S\) 中的连通块能不能合并,直接做是 \(O(3^n)\) 的。考虑优化,我们希望通过集合幂级数来优化,但是此时我们的转移并不是卷积形式,考虑将最优化改为判定,设 \(g_{i,S}\) 表示集合 \(S\) 中的连通块能否合并为 \(i\) 个连通块,此时转移就是 \(g_i=g_{i-1}\times f\),注意这里的乘法是子集卷积。直接做是 \(O(m^32^m)\) 的,还是无法通过。

注意到本题本质是最优化,如果两个集合有交一定是不优的,因此可以将子集卷积改为或卷积。然后每一次卷完我们不用还原,因为我们本质上只需要 \(g_{i,U}\) 的结果,可以单次 \(O(2^m)\) 求值。于是就做完了,复杂度 \(O(m2^m)\)

posted @ 2026-07-17 17:22  UKE_Automation  阅读(19)  评论(0)    收藏  举报