Codeforces 做题记录

2025-6-23

446B

\(2000\),绿。贪心,优先队列。

直接行或列取最大值是错的。注意到最终的总答案与操作的顺序无关(操作的顺序就是先减后减的问题)。因此我们不妨先执行所有行操作再执行所有列操作。设执行行操作 \(i\) 次,列操作 \(k-i\) 次,则一共产生 \(i\times(k-i)\) 个交点(严格说不是交点,是行列交叉次数,可以多次在同一点,计算多次),即总答案减去 \(p\times i\times(k-i)\)。行与行、列与列之间是互不干扰的,可以分别使用优先队列维护即可。

Submission

1044A

\(1700\),蓝。二分,双指针。

注意到横着的障碍如果左端点不是 \(1\) 那么是一定不用拆的(要么把挡在它下面的左端点是 \(1\) 的障碍直接拆掉,要么拆掉若干个竖的障碍然后把左端点是 \(1\) 的障碍绕掉,反正拆了也没用,左端点是 \(1\) 的还会挡着)。那么对竖的障碍和有效的横的障碍分别按横坐标排序后,考虑二分答案,判定时如果当前已经能够拆完水平障碍就可以(除去能绕开的),否则花费 \(1\) 次拆掉最靠左的竖的障碍,继续下去即可。

注意 \(l=1,r=10^9\) 的情况,此时直接拆掉即可。

Submission

131F

\(2000\),绿。二分,双指针。

先枚举矩形左上角坐标 \((x_1,y_1)\),以及右下角横坐标 \(x_2\),则可得右下角纵坐标 \(y_2\in [y_1,m]\)。显然,随着 \(y_2\) 的增大,矩形内符合图形的数量只增不减,故可以二分出第一个位置使得该数量恰好为 \(k\)。计算矩阵内符合图形的数量使用二位前缀和。时间复杂度 \(O(n^2m\log m)\)

Submission

142A

\(1600\),绿。暴力,数学。

首先枚举 \(i\)\(1\)\(\lfloor\sqrt[3]{n}\rfloor\),先判断是否 \(i\mid n\)。若是,则分两类讨论,分别对 \(i\)\(\frac{n}{i}\) 继续分解成两个因数乘积形式。然后对所有可能对应的情况分别求 \(\max,\min\) 即可。注意答案要减去 \(n\)(是被偷走的)。

Submission

342C

\(1900\),紫。几何。

显然,每一层恰好能放下两个球(事实上这也是最优的方案),那么下面一共可以放 \(\lfloor \frac{h}{r} \rfloor \times 2\) 个球,剩余 \(h - \lfloor \frac{h}{r} \rfloor \times r+r\) 的高度,记 \(h'=h-\lfloor \frac{h}{r} \rfloor\times r\) 为立方体部分剩余高度。最上面至少能放 \(1\) 个球,至多 \(3\) 个。分类讨论:

  • 如果放 \(3\) 个,则必须满足 \(\frac{\sqrt{3}}{2}r+r\le h'+r\),即 \(\frac{\sqrt{3}}{2}r\le h'\)。此时三个球的球心构成等边三角形。
  • 如果放 \(2\) 个,则两个球的球心必须在半圆形直径以下,即 \(\frac{r}{2}\le h'\)
  • 否则只能且一定放 \(1\) 个球(半圆形完全没有占用,肯定放得下)。

Submission

2025-6-25

11D

\(2200\),蓝。状压 dp,(记忆化搜索)。

记忆化搜索做法:

设当前从 \(i\) 号点开始遍历,那么只遍历编号大于 \(i\) 的点(这样做可以避免一个环重复统计)。设 \(f_{to,u}\) 表示当前已经访问的点集为 \(to\),在 \(u\) 号点,那么如果 \(u\) 能到达 \(i\),则 \(f_{to,u}\)\(1\),否则找满足遍历条件且未访问的点遍历下去。将 \(f\) 初始化为 \(-1\) 表示该状态未访问,\(0\) 表示没有环。

Submission

状压 dp 做法:To be updated.

12D

\(2400\),蓝。数据结构。

赛时复杂做法:显然就是三维偏序,\(b,i,r\) 分别对应 \(a,b,c\),直接 CDQ 分治即可。

坑点:

  • 输入是输入三行,每行 \(n\) 个,不是每行输入一个人。
  • 选择划分点时左右两侧的 \(a\) 必须不同(因为没有等于号,否则更新时会出错)。
  • 排序从大到小排。
  • 归并时选择左序列不能立刻修改,因为 \(b\) 可能相等,必须用另外一个指针从前往后移动,把大于的加入树状数组。
  • 剩余未加入树状数组的也要加入,最后再一起删除。

时间复杂度 \(O(n\log^2n)\)

Submission

\(a,b,c\) 含义同上。由于没有要求统计数量,故不需要 CDQ 分治。

简单做法:首先按 \(a\) 从大到小排序,然后开权值线段树,线段树的下标代表 \(b\),权值是这个 \(b\) 对应的所有 \(c\) 的最大值。这样我们只需要对 \(b\) 离散化后在 \([b+1,B]\) 中查询 \(c\) 的最大值并判断即可,同时支持单点修改。时间复杂度 \(O(n\log n)\)

Submission

16E

\(1900\),蓝。概率、状压 dp。

\(f_{i,0}\) 表示上一天 \(i\) 状态的概率,\(f_{i,1}\) 表示这一天 \(i\) 状态的概率,\(1\) 为存活,\(0\) 为死亡,则朴素的转移是从 \(i\) 状态中选择两个不同的为 \(1\) 的位置 \(j,k\),选到这两个位置的概率为 \(p=\frac{2}{\operatorname{popcnt}(x)\times(\operatorname{popcnt}(x)-1)}\)(总对数的倒数),则有转移(以 \(j\)\(k\) 为例,由于 \(j,k \in [1,n]\),所以在一次转移中强制前者吃后者):

\[f_{i \operatorname{xor} 2^{k-1},1} \leftarrow f_{i \operatorname{xor} 2^{k-1},1} + f_{i,0}\times p\times a_{j,k} \]

时间复杂度 \(O(2^nn^3)\),不能接受。考虑预处理,发现最后一项 \(a_{j,k}\) 可以使用乘法分配律,那么可以先预处理出每个状态中存活的鱼吃掉某条特定的鱼的概率总和,那么就可以不必枚举吃它的是那条鱼。两部分时间复杂度都是 \(O(2^nn^2)\),可以通过。

Submission

18D

\(2000\),蓝。dp,高精度。

\(f_i\) 表示前 \(i\) 个事件发生后的最大收益,如果第 \(i\) 个事件是获得硬盘,则 \(f_i \leftarrow f_{i-1}\),否则二分找到最大的 \(j\) 使第 \(j\) 个事件得到的硬盘与当前需要的相同(尽可能减少对前面的影响。可以预处理每种硬盘对应的事件编号),则 \(f_i\leftarrow \max (f_j+2^x,f_{i-1})\)。实现时需要高精度,可以开结构体重载运算符以简化代码。

实测发现不需要二分查找 \(j\),直接暴力找也能通过,而且时空几乎一样。

Submission

23C

\(2500\),蓝。构造。

挺神奇的思维题。

首先将所有元素按 \(a\) 从大到小排序,考虑交叉选,即要么 \(a_1,a_3,a_5,\cdots,a_{2n-1}\),要么 \(a_1,a_2,a_4,\cdots,a_{2n-2}\)。无论选哪种,\(a\) 一定满足要求(前者 \(a_1>a_2,a_3>a_4,\cdots,a_{2n-3}>a_{2n-2}\),各式相加即可,后者 \(a_2>a_3,a_4>a_5,\cdots,a_{2n-2}>a_{2n-1}\),同理)。那么只需要考察对应 \(o\) 的情况,若一组不可以(即不到一半),那么另外一组一定可以(总和一定),所以一定有解,直接排序输出即可。

Submission

25E

\(2200\),蓝。哈希。

显然可以暴力确定三个字符串的顺序,并且至少一个字符串要完整取。不妨强制完整取中间的字符串,则通过哈希计算左边后缀与中间前缀的最大公共长度(另外一个循环判中间是否包含左边),以及中间后缀与右边前缀的最大公共长度(另外一个循环判中间是否包含右边),用三个字符串总长度减去重叠部分即可。

Submission

1774D

\(1600\),绿。构造,贪心。

首先 \(1\) 的总个数不能被 \(n\) 整除时无解。

否则一定有解(因为每一列上的 \(1\) 的位置都可以随意变动,故实际上相当于可以随便放)。为了步数最少,一定是用缺少 \(1\) 行的 \(0\) 与过多 \(1\) 行的 \(1\) 交换,这样能同时使两行更接近答案。实现时先枚举列,再根据每行的情况找出上面两种行,并一一配对交换即可。时间复杂度 \(O(\sum nm)\)

Submission

2025-6-26

27E

\(2000\),蓝。dp,数论。

设答案 \(ans=p_1^{a_1}p_2^{a_2}\cdots p_k^{a_k}\),则有 \(n=(a_1+1)(a_2+1)\cdots (a_k+1)\)。由于 \(2^{10}=1024>1000\),故最多只用到前 \(10\) 个质数。考虑 dp,对 \(n\) 质因数分解 \(b_1,b_2,\cdots,b_m\),设 \(f_{i,k}\) 表示前 \(i\) 个质因子,用了前 \(k\) 个质数的最小答案。根据贪心显然将大的指数分配给较小的数能使答案更小,故先将质因子从大到小排序。那么有转移

\[f_{i,k}=\min_{1\le j<i} f_{j,k-1}\times prime_k ^{(\prod_{l=j+1}^{i}b_l)-1} \]

注意爆 long long 等问题。可以预处理出每个质数在 \(10^{18}\) 内的最大次幂。

Submission

28B

\(1600\),黄。并查集,搜索。

显然两个位置能交换可以在两个点间建无向边,之后判断么每对 \(i\)\(p_i\) 是否连通即可。

Submission

33D

\(2000\),绿。暴力,最短路。

由于任意两个圆没有交点,故不存在翻一次栅栏能穿过两个圆。那么对于每个栅栏,如果两个点一个在内一个在外,则必须翻,否则不用翻。时间复杂度 \(O(mk)\),可以通过。

Submission

37C

\(1900\),蓝。贪心,构造。

将每个 01 串看作一个二进制数,将长度从小到大排序,对于当前第 \(i\) 个串,首先在第 \(i-1\) 个串的基础上加 \(1\)(如果不能加 \(1\) 即爆位数则无解),如果长度相同则无需任何操作,否则按照缺少的长度从后面补 \(0\)。这样做能保证长度短的不为长度长的前缀,且尽可能的多填数。

Submission

38E

\(1800\),绿。dp。

首先将弹珠按坐标从小到大排序。设 \(f_i\) 表示前 \(i\) 颗弹珠,强制固定第 \(i\) 颗弹珠的最小代价,则有显然的转移:

\[f_i=\min_{1\le j <i}f_j+\sum_{k=j+1}^{i-1}(x_k-x_j)+c_i \]

将和式展开,使用前缀和维护 \(x_k\) 的和,可以做到 \(O(n^2)\)。可以在最后再放入一颗弹珠 \(n+1\) 并令 \(c_{n+1}=0\),可以避免边界问题。

Submission

49E

\(2300\),蓝。dp。

记字符集大小 \(A=26\)

我们并不关心一段字符串怎么变化,只关心变化之后能得到什么字母。设 \(f1_{i,j,z}=0/1\) 表示字符串 \(s_1\)\([l,r]\) 子串不可以/可以变成字母 \(z\)。枚举合并点 \(k\),则有

\[f1_{i,j,z} \leftarrow f1_{i,j,z} \operatorname{or} ( f1_{i,k,x} \operatorname{and} f1_{k+1,j,y} \operatorname{and} mp_{x,y,z}),i\le k <j \]

其中 \(mp_{x,y,z}=0/1\) 表示两个字母 \(x,y\) 不可以/可以合并为 \(z\)。同理对 \(s_2\) 预处理出 \(f2\)。此部分时间复杂度 \(O((n^3+m^3)A^3)\)

预处理完后,就可以开始比较 \(s_1,s_2\) 了。设 \(f_{i,j}\) 表示 \(s_1,s_2\) 分别到第 \(i,j\) 个位置的共同祖先的最短长度。枚举 \(1\le k <i,1\le l <j\),若 \(s_1\)\([k+1,i]\) 子串与 \(s_2\)\([l+1,j]\) 子串可以得到相同的字符,则 \(f_{i,j}\leftarrow \min(f_{i,j},f_{k,l}+1)\)。初始化 \(f\)\(+\infty\)\(f_{0,0}=0\)。若 \(f_{n,m}\)\(+\infty\) 则无解。此部分时间复杂度 \(O(n^2m^2A)\)

Submission

1854A1/1854A2

\(1400/1900\),黄/蓝。构造,数学。

A1

一个值全部非负或全部非正的序列可以通过 \(n-1\) 次操作使其单调不降。前者可以从前往后做一遍前缀和,后者可以从后往前做一遍后缀和。这部分最多需要 \(19\) 次操作。考虑如何把原序列变成上述序列,发现让每个数都加上绝对值最大的数,都能使其符号与该数相同,于是让每个数加上即可。最多 \(2(n-1)\le 38\) 次,可以通过。

Submission

A2

上述算法不足之处在于使序列化为同号消耗次数过多。在该题目限制下,最多可以用 \(31-19=12\) 次操作。设与绝对值最大的数同号的数有 \(k\) 个,则 \(k\ge 8\) 时,\(n-k\le 12\),可行。若 \(k<8\),不妨取与之异号且绝对值最大的数。又由于原始值域 \([-20,20]\)\(2^5>20\),故最多自加 \(5\) 次即可跳出值域外,从而绝对值比其他任何数都大。总消耗次数 \(5+k\le 5+7=12\),同样满足条件。

注意实现时 \(0\) 最好直接忽略,特判初始序列已经全部非负或非正。

Submission

2025-6-27

2025-6-30

182C

\(2000\),绿。贪心,数据结构。

根据贪心策略,应当选择 \(k\) 个最小的负数改为正数,或选择 \(k\) 个最大的正数改为负数,才可能使答案最大。那么可以先把数按正负分开,并确定每个数在同符号数中的排名。建立权值线段树,记录每个数出现的次数、单个数大小、总贡献和,查询时类似线段树二分,如果数值较大的区间不够用,就往数值较小的区间递归,否则在其内部递归。循环时分别维护当前的正数和、负数和。时间复杂度 \(O(n\log n)\)

Submission

185D

\(2600\),蓝。数论,数学。

大胆猜测,所有数的最大公约数一定很小:偶数时为 \(1\),奇数时为 \(2\)。设两个正整数 \(n,m\)\(n<m\),最大公约数 \(\gcd(k^{2^n}+1,k^{2^m}+1)=d\),则有 \(k^{2^n}\equiv k^{2^m} \equiv -1\pmod d,k^{2^{n+1}} \equiv (k^{2^{n+1}})^{\frac{2^m}{2^{n+1}}} \equiv k^{2^m} \equiv 1 \pmod d\),故 \(-1 \equiv 1 \pmod d\),即 \(d\) 只能为 \(1\)\(2\),当且仅当 \(k=1\)\(d=2\)

现在要求 \((k^{2^l}+1)(k^{2^{l+1}}+1)\cdots(k^{2^r}+1)\)。这个式子的意义可以理解为二进制上每一位选或不选,那么每一个 \(k\) 的幂一定恰好出现一次,则答案为 \(\dfrac{k^{2^{r+1}}-1}{k^{2^l}-1}\)。比如 \((k^1+1)(k^2+1)(k^4+1)=k^0+k^1+\cdots+k^7=\dfrac{k^8-1}{k-1}\)\(l,r+1\) 的两个分式可以消去分子)。直接使用逆元计算即可。以下是特殊情况:

  • 分母为 \(0\) 时,\(k^{2^l} \equiv 1 \pmod p\),后面 \(k\) 的幂也是同样的结果,直接输出 \(2^{r-l+1}\) 即可。
  • 使用费马小定理减小指数,注意此时模数为 \(p-1\)\(p=2\) 时不符合使用条件,直接特判即可)。
  • 如果 \(k\) 是奇数,最后再乘上 \(2^{r-l}\) 的逆元即可(乘多的部分)。

Submission

201C

\(2000\),绿。dp。

最优的方案应该是先往一个方向走,然后走回来,再往另一个方向走不回来。考虑用 dp 模拟这个过程。设 \(f_{i,0/1}\) 表示从第 \(i\) 个点出发往左走,不一定/一定回到 \(i\) 号点的最大次数,则有转移:

\[\begin{array}{l} f_{i,1}=f_{i-1,1}+a_{i-1}-[2 \nmid a_{i-1}]\\ f_{i,0}=\max\left\{ \begin{array}{l} f_{i-1,0}+a_{i-1}-[2 \mid a_{i-1}]\\ f_{i-1,1}+a_{i-1}\\ f_{i,1}\\ \end{array} \right. \end{array} \]

转移的意义分别是:

  • \(i\) 出发,把 \(i-1\) 左边走完以后,不停在 \(i-1\)\(i\) 之间移动,最终在 \(i\) 结束。
  • \(i\) 出发,先在 \(i-1\)\(i\) 之间移动,最终到 \(i-1\),走 \(i-1\) 左边的点。
  • \(i\) 出发,把 \(i-1\) 左边走完以后,不停在 \(i-1\)\(i\) 之间移动,最终在两者任意一个结束。
  • 可以回到 \(i\)

同理维护出向右走的最大次数。时间复杂度 \(O(n)\)

Submission

207B1/207B2/207B3

\(1600/1700/1900\),黄/绿/绿。dp,倍增,ST 表。

首先破环为链,将原序列复制一次变为长 \(2n\) 的新序列。

\(f_i\) 表示最少次数,则有转移:

\[f_i=\min_{j=\max(i-a_i,1)}^{i-1} f_j+1 \]

一共要 \(n\) 轮,每轮时间复杂度 \(O(n^2)\),总时间复杂度 \(O(n^3)\)

考虑优化。有一个贪心,即如果对于一个位置 \(j\),其 \(j-a_j\) 的值比较小(更靠近最前面),那么其需要的次数一定不会多于 \(j-a_j\) 较大的。那么有效的决策点只有一个,即是 \(j \in [\max(i-a_i,1),i-1]\)\(j-a_j\) 最小的 \(j\)。可以通过 ST 表预处理做到 \(O(n\log n+n^2)\)

继续优化。既然已经知道上一次从哪传递过来,那么就根本不用 dp 了。使用倍增优化传递的过程即可做到 \((n\log n)\)。注意倍增只跳到一个点 \(i\),其对应的 \(j\) 满足 \(j-a_j>1\),即跳到 \(i\) 后,再额外花费 \(2\) 步。

Submission

208E

\(2100\),蓝。树上启发式合并。

将题目转化为统计距离某节点为定值的点的数量。直接使用树上启发式合并即可,维护每个深度的点的数量,并将挂在当前节点上的询问一并处理即可。时间复杂度 \(O(n\log n)\)

Submission

209C

\(2400\),蓝。图论,并查集。

存在欧拉回路的充要条件:

  • 图是连通图
  • 每个点的度数为偶数

那么先用并查集求出原图中的所有连通块。由于只要求以 \(1\) 为起点终点的欧拉路径,故只需考虑 \(1\) 所在的连通块以及内部有连边的连通块。如果一个连通块内只有偶点,则要向外连两条边,否则选两个奇点各向外连一条边,其余奇点两两配对。由于向外连的每条边都计算了 \(2\) 次,因此无论是一个偶点还是两个奇点都只产生 \(2 \div 2=1\) 的贡献。

Submission

225C

\(1700\),绿。dp。

简单 dp。设 \(f_{i,0/1}\) 表示前 \(i\) 列,将第 \(i\) 列染成白色/黑色的最小代价,则有转移:

\[f_{i,0}=\min_{j=i-y}^{i-x}(f_{j,1}+\sum_{k=i-x+1}^{i}cost_{k,0})\\ f_{i,1}=\min_{j=i-y}^{i-x}(f_{j,0}+\sum_{k=i-x+1}^{i}cost_{k,1}) \]

预处理出将每列染成白色/黑色的代价,并对列求前缀和即可做到 \(O(m^2)\)

Submission

2025-7-1

292D

\(1900\),蓝。暴力。

直接暴力模拟,最后使用 dfs 判断连通性,比并查集复杂度更低。时间复杂度 \(O(mk)\),可以通过。

Submission

292E

\(1900\),蓝。数据结构。

考虑分块。对修改操作,如果其覆盖了整个块,则在块的起点打上对应 \(a\) 的位置的标记,否则先将原标记下放,然后暴力修改。查询时将对应块的标记下放之后直接输出即可。时间复杂度 \(O(m\sqrt n)\)

Submission

更简单的做法是使用线段树维护对每个位置操作时间最晚的操作编号,然后要输出时直接在该位置执行对应操作即可。时间复杂度 \(O(m\log n)\)

294B

\(1700\),绿。贪心,dp。

根据贪心,对于厚度相同的书,应该把宽度较大的竖着放在下面,上面放得下的机会更大。又由于厚度只有 \(1,2\),故可以枚举放在下面的书的总厚度,并枚举 \(1,2\) 厚度的书的数量,并判断剩下宽度较小的书(已排序)能否放在上面即可。时间复杂度 \(O(n^2)\)

Submission

294E

\(2300\),蓝。dp。

考虑 dp。设 \(f_u\) 表示以 \(u\) 为根的子树中每个点到 \(u\) 的距离之和,则有 \(f_u=\sum_{v\in son_u}f_v+w_{u,v}\times size_v\)。通过换根操作即可以 \(O(n)\) 的复杂度求出路径和(注意要除以 \(2\))。

接下来枚举断掉哪条边,那么遍历时分别从这条边的两个端点 \(u,v\) 出发,不经过这条边,分别做一遍上文中的 dp 以及换根,求出两棵子树内部路径和 \(s_1,s_2\) 以及到某一点的最小距离和 \(m_1,m_2\)。新的边应该建在取最小距离和的两点 \(x,y\) 间,则总路径和为

\[s_1+s_2+m_1\times size_v+m_2 \times siz_u+w_{u,v}\times size_u \times size_v \]

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

Submission

269C

\(2100\),绿。图论。

注意到题目保证有解,且不存在环,那么 \(1\) 号点出边到达的点中一定存在至少一个点没有其它入边且流量守恒(否则就有环了)。只需找到这样的点,继续把它当作新的 \(1\) 号点即可。时间复杂度 \(O(n+m)\)

Submission

279C

\(1700\),绿。贪心。

题目即是要求 \([l,r]\) 区间内是否单峰。那么只需预处理求出每个位置后面的第一个山峰和第一个山谷,并判断是否出现了不止一次转折即可。时间复杂度 \(O(n+m)\)

Submission

274B

\(1800\),蓝。贪心,dp。

由于修改深度较大的节点会影响深度较小的节点,故应当先修改深度较大的节点才能避免后续操作被浪费。设 \(f_u,g_u\) 分别表示以 \(u\) 为根的子树需要 \(-1,+1\) 的最少次数,由于每次操作每个子节点 \(v\) 可选可不选,故有显然的转移 \(f_u=\max f_v,g_u=\max g_v\)。最后考察子节点的操作对当前节点 \(u\) 的影响,并使用对应次数的操作即可。时间复杂度 \(O(n)\)

Submission

2025-7-2

346A

\(1600\),黄。博弈,数论。

根据更相减损法原理,两个正整数 \(x,y\) 通过不断做差最终可以得到最小值为 \(\gcd(x,y)\),由此可以获得不超过 \(\max_{i=1}^n a_i\)\(\gcd(x,y)\) 的所有倍数。那么只需要找到原序列选任意个数的 \(\gcd\) 的最小值 \(g\)(当全选时最小),答案即为 \(\lfloor \dfrac{\max_{i=1}^n a_i}{g}\rfloor -n\)

Submission

346B

考虑 dp。设 \(f_{i,j,k}\) 表示 \(s\) 的前 \(i\) 位,\(t\) 的前 \(j\) 位,匹配到 \(g\) 的前 \(k\) 位的长度最大的字符串。显然有转移 \(f_{i,j,k} \leftarrow \max(f_{i-1,j,k},f_{i,j-1,k})\)。额外地,当 \(s_i=t_j\) 时,则可以把该位加入字符串末端,并使用 KMP 更新当前匹配到第几位。上述各种情况取最大值即可。

Submission

348C

\(2500\),紫。根号分治。

关键性质:大小超过 \(\sqrt{n}\) 的集合数量不超过 \(\sqrt{n}\) 个,其余集合大小不超过 \(\sqrt{n}\)。考虑根号分治,对于大小超过 \(\sqrt{n}\) 的集合,由于这样的集合数量较少,因此修改时可以直接维护对每个这样的集合的总贡献(集合的交集大小可以预处理)。查询时如果是小集合就把大集合的标记下放给它,最后再回收。具体如下:

  • 修改时如果是小集合,那么先暴力修改每个对应的元素,再更新每个大集合的总和(小对大);如果是大集合,则打上标记,并更新每个大集合的总和(大对大)。
  • 查询时如果是小集合,先暴力累加对应元素的和(小对小),再加上每个大集合的标记乘上交集的大小(大对小);如果是大集合,直接输出即可。时间复杂度 \(O((n+m+q)\sqrt{n})\)

Submission

350E

\(2200\),紫。图论。

考虑最多能构造多少条边。由于只需要一对点的最短路不正确即可,我们不妨让一对关键点的最短路不正确,即不能找到一个同样为关键点的转折点。那么只需要让这个关键点不与其它关键点连边即可(这样一定求不出最短路),即最多可以连 \(\frac{n(n-1)}{2}-(k-1)\) 条边。为了保证图连通,可以先让这个关键点与所有非关键点连边,再选一个非关键点与剩余关键点连边。剩下的边随便连。无解情况:

  • \(n=k\),此时即是标准的 Floyd。
  • \(m>\frac{n(n-1)}{2}-(k-1)\),超过边数最大值。

Submission

351B

\(1900\),蓝。概率,dp。

显然,先手每次一定能减少 \(1\) 对逆序对,后手有 \(\frac{1}{2}\) 概率减少 \(1\)\(\frac{1}{2}\) 概率增加 \(1\)。设 \(f_n\) 表示有 \(n\) 对逆序对的期望操作次数,则有 \(f_n=2+\dfrac{f_{n-2}}{2}+\dfrac{f_n}{2}\),即 \(f_n=f_{n-2}+4\)。又有 \(f_0=0,f_1=1\),故:

  • \(2 \nmid n\) 时,\(ans=2\times n-1\)
  • \(2 \mid n\) 时,\(ans=2\times n\)

直接统计原序列逆序对数量即可。

Submission

351C

\(2500\),紫。dp,广义矩阵乘法。

\(f_{i,j}\) 表示前 \(i\) 位,还有 \(j\) 个左括号未匹配,则有转移:

\[f_{i,j}=f_{i,j+1}+b_i,j=0\\ f_{i,j}=\min(f_{i,j-1}+a_i,f_{i,j+1}+b_i),j>0\\ \]

由于 \(a,b\) 的循环周期是 \(n\),故最多有效的未匹配的左括号是 \(n\) 个(再多就重复了),只需要考虑 \(f_{i,0},f_{i,1},\cdots,f_{i,\min(i,n)}\)。根据广义矩阵乘法的定义,上述转移可以写成广义矩阵乘法形式:

\[\left[ \begin{array}{} f_{i,0}\\ f_{i,1}\\ \vdots\\ f_{i,n} \end{array} \right] = \left[ \begin{array}{} +\infty & b_i & +\infty & \cdots & +\infty\\ a_i & +\infty & b_i & \cdots & +\infty\\ +\infty & a_i & +\infty & \cdots & +\infty\\ \vdots & \vdots & \ddots & \vdots & \ddots\\ +\infty & \cdots & a_i & +\infty & b_i\\ +\infty & \cdots & +\infty & a_i & +\infty\\ \end{array} \right] \left[ \begin{array}{} f_{i-1,0}\\ f_{i-1,1}\\ \vdots\\ f_{i-1,n} \end{array} \right] \]

其中 \(a_i,b_i\) 在最靠近对角线的两条直线上。由于广义矩阵对乘法满足结合律,故可以做到 \(O(n^3\log m)\)

Submission

有反悔贪心做法,先让所有位置都为右括号,修改为左括号的代价为 \(a_i-b_i\)。当左括号不足时,从当前位置往前(包括当前位置)寻找一个修改代价最小的改为左括号。前后长 \(n\) 的段直接暴力,中间易证周期为 \(2n\)

To be updated.

2025-7-3

1848C

\(1800\),绿。数论。

首先排除 \(a=b=0\) 的情况(此时无论执行多少次操作都有 \(a_i=0\))。

接下来考虑 \(a\) 等于 \(0\) 后继续操作会发生什么变化。模拟可得 \((0,b) \rightarrow (b,b) \rightarrow (b,0) \rightarrow (0,b)\),可以发现是以 \(3\) 为周期的循环。因此有解的条件是达到 \(a=0\) 状态的操作数在模 \(3\) 意义下相同。

不妨从奇偶性的角度考虑需要多少次操作。记奇数为 \(1\),偶数为 \(0\)。分情况讨论:

  • \(a\) 为偶数,\(b\) 为奇数,则有 \((0,1) \rightarrow (1,1) \rightarrow (1,0) \rightarrow(0,1)\),操作次数在模 \(3\) 意义下为 \(0\)
  • \(a\) 为奇数,\(b\) 为偶数,则有 \((1,0) \rightarrow (0,1) \rightarrow (1,1) \rightarrow (1,0)\),操作次数在模 \(3\) 意义下为 \(1\)
  • \(a,b\) 为奇数,则有 \((1,1) \rightarrow (1,0) \rightarrow (0,1) \rightarrow (1,1)\),操作次数在模 \(3\) 意义下为 \(2\)
  • \(a,b\) 为偶数,令 \(a\leftarrow \frac{a}{2},b\leftarrow \frac{b}{2}\),则转化为上面三种情况。

之所以使用奇偶性分类讨论是正确的,是因为题目中规定的运算使得不可能连续两次 \(a=0\)(此时 \(a=b=0\),已经排除)。又由于 \(0\) 为偶数,故 \(0\) 一定对应着上面的某个 \(0\)

Submission

2025-7-4

380C

\(2000\),绿。数据结构。

可以考虑类似求区间最大子段和的思路,使用线段树维护区间内已匹配长度,以及多余的左、右括号数量,合并子节点信息时根据位置关系匹配多余的左、右括号并更新匹配长度,再记录剩余的左、右括号总数量。时间复杂度 \(O(n+m\log n)\)

Submission

379D

\(2000\),绿。暴力,分类讨论。

对于可能对答案产生贡献的位置分为两种,第一种是 \(s_1,s_2\) 内部,第二种是连接操作时的连接处。我们不妨设 \(s_1\) 中有 \(x\) 个,\(s_2\) 中有 \(y\) 个,通过递推预处理出 \(s_n\) 对应 \(x,y\) 的系数,以及 \(s_1+s_1,s_1+s_2,s_2+s_1,s_2+s_2\) 每种连接点的数量。接着暴力枚举每种连接点是否出现,从而确定 \(s_1,s_2\) 的首末位是否需要强制取特定字母,在此基础上再暴力枚举 \(x,y\)(因为 $ 1\le n,m \le 100$,故 \(1\le x,y \le 50\)),判断是否恰好相等以及此时剩余位置是否能够放得下即可。

Submission

388C

\(2000\),蓝。贪心,博弈。

结论:对于 \(m\) 为偶数,双方各取一半;\(m\) 为奇数,最中间的数谁取到看其在所有这类数中的排名。感性理解,如果有一个大数更靠近某个人,那么当对方想拿这个数时,己方可以与其同时操作从而避免被拿。中间的数到两人距离相同,那么就看先后手。最大的数归先手,次大归后手,以此类推。时间复杂度除排序线性。

Submission

413D

\(2000\),蓝。dp。

合并操作可以看作两个数直接相加,那么只需考虑连续一段求和。考虑 dp,设 \(f_{i,j}\) 表示前 \(i\) 个数,当前和为 \(j\) 的方案数(超过 \(2^k\) 的也用 \(2^k\) 代替)。分类讨论转移:

  • \(a_i=2\),则有 \(f_{i,\min(j+2,2^k)} \leftarrow f_{i,\min(j+2,2^k)} + f_{i-1,j}\)\(2\) 通过不断添加可以合并任意数)。
  • \(a_i=4\),若 \(j \equiv 2 \pmod 4\),说明此时最后一位是 \(2\),不能合并,必须重新求和,\(f_{i,4} \leftarrow f_{i,4}+f_{i-1,j}\);否则可以合并,\(f_{i,\min(j+4,2^k)} \leftarrow f_{i,\min(j+4,2^k)} + f_{i-1,j}\)
  • \(a_i=0\),把上面两种情况各处理一次即可。

答案即为 \(f_{n,2^k}\)。时间复杂度 \(O(2^kn)\)

Submission

427C

\(1700\),绿。缩点。

tarjan 模板题。题目条件即是要求每个强连通分量内必须有一个检查站。那么缩点后统计每个强连通分量内的最小值及数量,并将最小值相加,数量相乘即为答案。时间复杂度 \(O(n+m)\)

Submission

425E

\(2500\),蓝。dp。

有效线段为与前面已选线段不相交的线段。设 \(f_{i,j}\) 表示当前最后一条有效线段右端点为 \(i\)(其它线段右端点不超过 \(i\)),函数值为 \(j\) 的方案数。考虑枚举上一条有效线段的右端点位置 \(k\),则有 \([k+1,i],[k+2,i],\cdots,[i,i]\)\(i-k\) 条线段可作为最后一条有效线段。由于每条选不选都只有 \(1\) 的贡献,且至少选一条,故有 \(2^{i-k}-1\) 种方案。剩下的形如 \(1\le l\le k,k<r\le i\) 的线段 \([l,r]\),选不选均可,故有 \(2^{k\times (i-k)}\) 种方案。于是可以写出总转移式:

\[f_{i,j}=\sum_{k=j-1}^i f_{k,j-1} \times (2^{i-k}-1) \times 2^{k\times (i-k)} \]

初始值 \(f_{0,0}=f_{i,0}=1\),后者是避免乘法结果为 \(0\)\(k\)\(j-1\) 开始枚举是因为 \(j-1\) 条有效线段至少需要 \(j-1\) 的值域空间。

Submission

posted @ 2025-09-12 08:14  FormulaOne  阅读(20)  评论(0)    收藏  举报