CSPS2026 前做题记录

蒟蒻之前好多题没补 / 做过挺多题没总结,CSPS 之前吃一下

C1592. 😅

乱贪题。

其实根本不知道怎么证的,感觉很显然,就是你考虑离自己最近的没放。

然后这相当于用一个数给区间取 \(\min\),直接离线用一个支持区间覆盖的线段树。

也可以用栈模拟。

C1593. 🕒

考虑到最后能收缩到一个区间里。

然后倍增,对每个倍增的层里建一个 ST 表。

复杂度 \(O(n\log^2n)\)。

Dea9c. 小球消除

比较板子的区间 dp。

随便贺几种合并策略就行了。

CF1902F

点分树板子。

我们把对于 \((u,v)\) 的询问挂到点分树上,然后重跑一遍点分治,随便贺一下线性基就能 \(O(n\log n\log^2V)\)。

D1rq3. 课程值班

由于它们互不影响,贡献独立,所以我们直接对它们的贡献背包即可。

问题来了:设某个助教值班为 \(m\) 个长为 \(2\) 的块,那么方案数为多少?

不妨考虑第 \(i\) 个块与第 \(i+1\) 个块中间间隔了 \(x_i\) 天(\(1\leq i\leq m-1\)),第一个块前面留空了 \(x_0\) 天,最后一个块后面留空了 \(x_m\) 天。则有:\(x_0,x_m\geq 0,\forall 1\leq i\leq m-1,x_i\geq 1,\sum_{i=0}^mx_i=n-2m\)。我们发现,\(x\) 可以唯一确定一种方案,故考虑计数上面的不定方程的方案数。

最难以处理的是 \(x_1\sim x_{m-1}\) 都是正数。考虑将它们都减一,使得其取值范围变为非负数,那么此时的和是 \(n-2m-(m-1)=n-3m+1\)。根据插板法直接计数变量均为非负整数的不定方程数量,可得

\[ans=\binom{(n-3m+1)+(m+1)-1}{(m+1)-1}=\binom{n-2m+1}{m} \]

那么这就是某位助教选择 \(m\) 段的贡献。对其背包即可。

注意预处理组合数,则复杂度瓶颈在背包,为 \(O(K^2m)\)。

L7b92i. 树上查询

这题有点太牢了吧)

有经典结论:\(dep_{\texttt{LCA}_ {i=l}^ri}=\min_{i=l}^{r-1}dep_{\texttt{LCA}(i,i+1)}\)

于是原问题转化成了两个区间交的问题。

扫描线即可单 \(\log\)。

话说主席树 + 二分的双 \(\log\) 做法怎么能在 Tsinsen 上跑 \(80\),清橙神机畏惧了 /bx

D1qkh. 字符串集合

这题也够牢的。

我们把一个 \(k1+k2\) 的子串拆分成前 \(k1\) 的不同串和后 \(k2\) 的不同串。

这样我们对于每个 \(pre\) 里的串,对它们的 \(k1\) 子串连边。对每个 \(suf\) 里的串,被它们的 \(k2\) 子串连边。然后对于 \(k1+k2\) 在 \(mid\) 里的,对它们连边。

直接跑二分图最大匹配即可。

L7f1qg. 排水系统

拓扑排序板子。

Ldojnm. 字符串匹配

观察到 \(AB\) 一定是 \(s\) 的前缀,\(C\) 一定是 \(s\) 的后缀,且确定了 \(AB\) 和 \(i\) 就能唯一确定整个划分。

于是我们维护前后缀的 \(F\) 值,然后直接枚举 \(AB\) 长度和 \(i\) 即可,这样复杂度等价于调和级数。用前缀和计入 \(AB\) 的前缀的 \(F\) 值,直接累加即可。这样我们就能 \(O(n|\Sigma|+n\log n)\) 解决问题。

Lcduho. 子串

很显然的 dp,随便记几个匹配位置就行。

展示暴力 dp 通过。

L565sl. 编辑字符串

来自大佬的一个很厉害的证法。

首先有 \(ans=n-\sum_{i=1}^n(a_i-b_i)^2\)

\(\sum a_i^2+b_i^2\) 为定值,考虑最大化 \(\sum 2a_ib_i\)

我们的策略是尽量让两个 \(1\) 在前面配对,因为这至多会导致后面的一对 \(1\) 匹配不成功,显然是不劣的。

于是直接贪即可,不需要任何分类讨论。

代数神力 /bx

C4230. 🌲️

很聪明的转化。

极差不好处理,转化题意:我们划分出一堆联通块,在每个联通块里选择两个点,使得每个联通块的这两个点的差的和最大。我们发现,如果要求整体最大,那么每个联通块的两个点的差只能取极差。

对于在一个联通块选的两个点 \(u,v\),我们定义它们是匹配的。我们发现,对于所以划分出的匹配的二元组,它们合法当且仅当任意二元组所覆盖的路径都没有交。因为想要使匹配的两个点在同一联通块,就至少需要将它们树上路径上的点划分到同一联通块。

于是,我们将题意转化成这样:对于 \(n\) 个点,每个点赋一个权值 \(w_i\in \\{-1,0,1\\}\),使得每个 \(w_i=-1\) 的点都能给另一个 \(w_j=1\) 的点两两配对,且配对的两个点树上路径不会与另一个配对的两个点的树上路径相交。求 \(\max\sum_{i=1}^na_iw_i\)。

考虑 dp:令 \(f_{u,0/1/2}\) 表示以 \(i\) 为根的子树内,已经全部匹配 / 有一个 \(1\) 没匹配 / 有一个 \(-1\) 没匹配。

考虑初始化,对于 \(i\in leaf\),有 \(f_{i,0}=0,f_{i,1}=a_i,f_{i,2}=-a_i\)。

考虑转移。对于 \(f_{u,0}\),我们可以让它的所以儿子子树全都匹配完,或者恰好有子树 \(x,y\) 内的两个点可以配对,让它们经过点 \(u\) 进行配对。或者某个子树内的点没有配对,来找点 \(u\) 配对。就有:

\[f_{u,0}=\max(\sum_vf_{v,0},f_{x,1}+f_{y,2}+\sum_{v\neq x,v\neq y}f_{v,0},f_{x,1}-a_u+\sum_{v\neq x}f_{v,0},f_{x,2}+a_u+\sum_{v\neq x}f_{v,0}) \]

对于 \(f_{u,1}\),可以让所有子树都配对好,自己没配对,或者直接取某个没配对好的子树,可得

\[f_{u,1}=\max(a_u+\sum_vf_{v,0},f_{x,1}+\sum_{v\neq x}f_{v,0}) \]

那么 \(f_{u,2}\) 的转移就类似了,有

\[f_{u,2}=\max(-a_u+\sum_vf_{v,0},f_{x,2}+\sum_{v\neq x}f_{v,0}) \]

答案显而易见就是 \(f_{1,0}\)。直接预处理子树 dp 值的前后缀 \(\max\) 就可以做到 \(O(n)\) 的时间复杂度。

CF316G3

这个是真套路吧)

把串都贺到一起,然后建立出后缀数组。

这样我们容易去处理本质不同。

考虑处理本质不同的时候我们会钦定左端点,那么此时具有单调性:由于 \(r\) 小的是 \(r\) 大的前缀,所以出现次数会单调不增

于是我们可以用 RMQ 和前缀和加上二分判断二分出满足条件的最小的右端点和最大的右端点,然后贡献就容易计算了。

L8af4. 儒略日

一年前写的,试图自己在推一遍。

勾石

Lc2fnj. 动物园

__int128 题。

容易求出所有被强制钦定不能选的位置数量,记为 \(c\),则 \(ans=2^{k-c}-n\)

L5o3d5. 幂次

\(b=2\) 时会爆炸,注意到 \(b=2\) 会产生 \(\lfloor\sqrt{n}\rfloor\) 的贡献,于是我们在后面的暴力统计里不在考虑完全平方数的贡献即可。

然后就是要手写二分开方。

ARC119 C

考虑怎么推平 \((l,r)\)。

首先要推平 \(A_l\),那么就需要对 \((l,l+1)\) 操作 \(A_l\) 次减法,得到 \(0,A_{l+1}-A_l\)

\(A_{l+1}\) 推导同理。

不难发现这样推平一定是合法的。如果中间推出来了负数,那么先进行一定的加法操作就行。比如说你在某一次推出来了 \(0,-x\),那么你就先对后面的那个数进行 \(x\) 次加法操作,这样就可以和那个负的抵消了。

最后可以得到 \(A_i\) 的变化量为 \(\sum_{j=l}^{i-1}(-1)^{i-j}A_j\)。

那么对于一个区间 \([l,r]\),它合法当且仅当 \(A_r=\sum_{i=l}^{r-1}(-1)^{r-1-i}A_i\)

提取公因项,得 \((-1)^{r-1}\sum_{i=l}^{r-1}(-1)^iA_i\)

构建前缀和 \(s_i=\sum_{j=1}^i(-1)^jA_j\),则有 \(A_r=(-1)^{r-1}(s_{r-1}-s_{l-1})\)

拆开得到 \(A_r-(-1)^{r-1}s_{r-1}=-(-1)^{r-1}s_{l-1}\)

由于 \((-1)^{r-1}\) 的取值只与 \(r-1\) 奇偶性有关,我们直接开两个 map 或两个哈希倒着扫一遍就行。

时间复杂度 \(O(n\log n)\) 或 \(O(n)\)。

CF240F

记字符集大小为 \(|\Sigma|\)

考虑线段树维护区间内的每个字符的出现次数,这样每次提取出桶,然后贪心求出最优回文串即可。

于是我们只需要实现一个维护区间字符出现次数和区间覆盖的线段树即可。

直接做就是 \(O(|\Sigma|n+|\Sigma|m\log n)\)。

所以这为啥能有 2600 啊???

Dm3es. Cow Patterns

这题当时场切了,但是后来又有人加数据卡我常???

先转化题意:求出 \(A\) 中有多少个长为 \(K\) 的子串,使得这个子串离散化后的结果与匹配模式串 \(B\) 离散化后的结果相同。考虑运用字符串哈希判断相等,于是我们的问题变成了如何求出一个子串离散化后的哈希值,考虑运用线段树维护。

首先维护一个桶 \(b\),\(b_i\) 表示第 \(i\) 个元素有没有出现。对 \(b\) 做前缀和,记前缀和数组为 \(c\),那么不难想到元素 \(i\) 被离散化后的值是 \(c_i\)。离散化后,考虑如何求哈希值。我们考虑元素 \(i\) 对原始哈希值的贡献,显然是 \(i\times \sum_{j}B^{x_j}\),其中 \(B\) 是进制。那么对于每个 \(i\),我们记后面的 \(\sum_jB^{x_j}\) 为 \(c^{'}_ i\),那么 \(i\) 对原始哈希值的贡献是 \(c^{'}_ i\),\(i\) 在替换为 \(c_i\) 后对现在哈希值的贡献就是 \(c_i\times c^{'}_ i\),于是新的哈希值就是 \(\sum_{i=1}^Sc_i\times c^{'}_ i\)。上述 \(b\)、\(c\)、\(c^{'}\) 数组的合并复杂度均为 \(O(S)\),所以总时间复杂度为 \(O(NS\log N)\)

P14254 分割(divide)

什么叫 \(O(nk)\) 拿了 96 分???

做了将近 1.5h、、

首先分析一下原题,可以得到两个关键性质:

  • 所有 \(b_i\) 的深度相同
  • 记分割后 \(S_i\) 内的最大深度为 \(mx_i\),则合法当且仅当 \(mx_1=\min_{i=2}^{k+1}mx_i\)

性质 1:如果 \(b\) 深度不相同的话,那交集肯定会把 \(b_1\) 交掉,显然是不合法的

性质 2:显然,每个子树内的深度是一个区间,于是原问题相当于区间交,就可以转化成这个

于是我们 dfs 搜出每个点的深度,把深度相同的点贺到一起去处理,记 \(f_u\) 表示原树中以 \(u\) 为根的子树的最大深度。
枚举每个点 \(u\) 作为 \(b_1\),那么考虑此时的两种情况:

  • 钦定分割后以 \(1\) 为根的子树最大深度大于 \(f_u\),则此时必须满足 \(\min_{i=2}^kf_i= f_u\)。
  • 钦定分割后以 \(1\) 为根的子树最大深度等于 \(f_u\),则此时必须满足 \(\min_{i=2}^kf_i\geq f_u\)

对于情况 \(1\),我们钦定 \(b_2\sim b_k\) 中有 \(j\) 个 \(f\) 等于 \(f_u\),其余大于 \(f_u\)。则组合数容易计算;对于情况 \(2\),相当于我们将本深度所有 \(f\) 大于 \(f_u\) 的点都选到 \(b_2\sim b_k\) 里了,于是方案就是选完所有大于的点后剩下的去等于里选的方案数,组合数计算即可。

这样 \(O(k)\) 计算方案 \(1\),\(O(1)\) 计算方案 \(2\),这样就 \(O(nk)\) 算完了答案,可以获得 \(96\) 分。

至于如何优化,只需要用范德蒙德卷积化简那个式子就能做到总体 \(O(n)\)。

L2fle7. 圣诞树

猜结论题?

注意到答案是排列且 \(n\leq 10^3\) 而且是个凸包,启示我们大概是一个类似于区间 dp 不断扩展左右端点求排列的过程。首先找到 \(k\),把数组旋转一下。这样我们记 \(dp_{l,r,0/1}\) 表示扩展完 \([l,r]\) 且目前位于 \(l\) / \(r\),那么直接 dp 即可 \(O(n^2)\),构造答案是 dfs 即可。

这能蓝???

L3usbm. 结构体

之前没做过,模拟赛 2h 才调完、、、只能说代码能力一坨

经典大模拟,每次递归访问一下就行

其实理清思路之后很好写

话说这也没有蓝吧

L5opsp. 接龙

写了 1h,其中 40min 都在卡常、、

显然的,把所有序列拼起来组成一个大序列 \(S\),考虑 \(dp_{i,j}\) 表示第 \(i\) 轮,到 \(S_j\) 是否可以。转移的时候更新一个区间用个差分就行。

但是卡常太恶心了 ///

L4l4po. 报数

就是一个很普通的筛法。

你注意到关键点只有 \(m=10^6\) 左右,你暴力筛就能调和级数 \(O(m\log V)\)。然后 \(O(V)\) 预处理一遍每个数的答案,就能单次 \(O(1)\) 查询了。

L14r43. 序列

写了一个复杂度 \(O(mn^2k^2)\) 的暴力 dp 状物然后跑的飞快?

二进制进位,直接考虑每个 bit 位。那么我们不难写出如下状态定义:设 \(dp_{i,j,k,x}\) 表示处理到第 \(i\) 个 bit 位,目前已经在 \(a\) 里填了 \(j\) 个位置,\(S\) 内目前有 \(k\) 个 \(1\),对下一个 bit 位的进位贡献为 \(x\)。转移时,我们枚举上一个的填的数量 \(j^{'}\)、\(1\) 的个数 \(k\) 和进位贡献 \(z\),则这次要填的数 \(t=j-j^{'}\),不难得到

\[dp_{i,j,k+(t+z)\bmod 2,\lfloor(t+z)/2\rfloor}=\binom{n-j^{'}}{t}v_i^{t}\sum_zdp_{i-1,j^{'},k,z} \]

直接预处理一下就能 \(O(1)\) 查询组合数。统计答案的时候枚举一下进位贡献和 \(1\) 的数量即可。

posted @ 2026-10-02 09:52  DeadFatsheep  阅读(14)  评论(0)    收藏  举报