
OJ刷题解题报告
文章平均质量分 65
_Equinox
分享学习过程
展开
-
观察+dp+组合恒等式,Codeforces 998 div3 F - Multiplicative Arrays
C(n+1,i+1)我们拆成阶乘,化简后,分子项数是log级别的,分母预处理阶乘逆元,不再赘述。那么我们对于每个x,枚举>1的长度i,计算C(n+1,i+1)*dp[i][x]即可。我们要计算f(i,x)*ΣC(j,i),j为a[]的长度,1<=j<=n。定义状态dp(i,j)为i个>1的数乘积为j的方案数。考虑k=1E5时,a[]中>1的数最多有多少个?每个x枚举>1的数字长度i。注意到n很大,没法算。原创 2025-01-20 02:06:05 · 444 阅读 · 0 评论 -
线段树优化dp,abc389F - Rated Range
那么我们用懒标记线段树维护f(i),每次读入l(i)r(i),对f值在l(i)和r(i)之间的线段进行+1即可。f(i,j)=f(i-1,j)+1,如果l[i]<=f(i-1,j)<=r[i]考虑定义f(i,j)为初始分数为j,经过i场比赛后的最终分数。时间复杂度:O(nlogn+q)空间复杂度:O(nlogn)显然具有单调性f(i,j+1)>=f(i,j)否则,f(i,j)=f(i-1,j)原创 2025-01-19 21:25:31 · 294 阅读 · 0 评论 -
二分+贪心+观察,abc389E - Square Price
k^2=(1+2k-1)*k/2,这相当于分别买了价格为P[i],3P[i],5P[i]...(2k-1)P[i]的物品。最终计算数目如果剩的钱购买x+1的话还要加上这一部分的贡献,具体为什么可以在混合数组上模拟下最优解可能长的样子。我们假如把所有物品混合,可能是P[0],P[1],2P[0],P[3],P[4].....根据x可以计算每个物品购买的数目,从而计算花费来check。如果给你一堆价格不同的物品,金钱有限的情况下怎么买买的最多?原创 2025-01-19 18:15:59 · 466 阅读 · 0 评论 -
二分图染色+线性dp,码蹄集OJ-聚会
放假了啊原创 2024-12-27 17:38:47 · 391 阅读 · 0 评论 -
差分 + 模拟,CF 815A - Karen and Game
我们计算 minrow[i] = min{g[i]},mincol[j] = min{ g[i][j] }一个经典的差分数组的模板题目:可以进行区间 + - 1,请问将数组变相等的最少操作次数?先操作行:那么每行都得操作 minrow[i] 次,然后列再补齐。先操作列:那么每列都得操作 mincol[j] 次,然后行再补齐。列操作会对每一个行差分数组在该列的值的影响相同。行操作不影响行差分数组的值(除了第一个)因而得出结论:所有行差分数组的值都相同。对称的考虑:所有列差分数组的值都相同。原创 2024-11-26 18:07:13 · 488 阅读 · 0 评论 -
树状数组+概率论,ABC380G - Another Shuffle Window
我们发现我们只需计算子数组内产生的逆序对,而对于一个数组而言,数组内任意两个数之间构成逆序对的数目为 1 / 2,而 k-数组 pair 的数目为 k * (k - 1) / 2,每个pair 贡献1个逆序对的概率为1/2,根据二项分布的数学期望计算公式:E = np可得,k-数组的逆序对贡献期望为 k * (k - 1) / 4。每个滑窗这一部分的贡献为 (tot - cur) * (n - k + 1),因为 n - k + 1个滑窗等概率,所以贡献比例相同,这一部分的答案我们滑窗过程中直接累加。原创 2024-11-16 23:33:51 · 650 阅读 · 0 评论 -
搜索,CF 1666L - Labyrinth
考虑 从 s出发,搜索到 t,然后从t 沿着反向边一路往上走,不经过s -> t路径上的点最终到达s,那么说明找到了 两条首尾相同且不相交路径。考虑从 s 开始dfs,额外添加参数 p 记录上一个点,rev 记录当前是否走逆向,如果当前为逆向那么后续只能逆向走。以及 遇到搜索过的点,如果当前为逆向并且 该点为s,其实可以接着搜(找到了答案)时间复杂度: O(N + M)空间复杂度:O(N + M)如下图,黑色为正向边路径,红色为反向边路径。搜索的时候注意不能在s 就开始走逆向。原创 2024-11-15 16:53:12 · 458 阅读 · 0 评论 -
递推 / minmax搜索,CF 1767D - Playoff
定义 lt[x] rt[x] 分别为 节点x子树内 <= x 权值的数的个数,节点x子树内 >= x 权值的数的个数。我们按照 [1, 1 << n] 的值 构造一棵 锦标赛树,每个节点有两个儿子,该节点为 两个儿子中的胜者。最终答案就是 [lt[0], (1 << n) - gt[i] + 1]我们将每层按照s 值 分层,我们发现连续层产出的胜者一定是一个区间。从上往下 层数从0开始,那么 s[i] 就是本层的博弈规则。最后一层叶子就是值的排列。如果 s[i] = 1。如果 s[i] = 0。原创 2024-11-14 23:40:12 · 430 阅读 · 0 评论 -
构造,CF 2029D - Cool Graph
时间复杂度: O(N + M)空间复杂度:O(N + M)最后一定能构造出一棵树。原创 2024-11-11 18:16:23 · 368 阅读 · 0 评论 -
思维,CF 1735D - Meta-set
我们只需枚举两个 set 相交的那个元素 x,假如 x 在 cnt[x] 个set 中出现,那么 x。对于 cnt[x] 我们 固定 a, b 就能得出 c,用 map 维护一下暴力预处理即可。时间复杂度: O(N^2 k log(N^2) k)空间复杂度:O(N^2 k)作为相交元素的贡献就是 (cnt[x] - 1) * cnt[x] / 2。考虑一个五元组<a, b, c, d, e>,最多有几个set?原创 2024-11-09 14:27:50 · 399 阅读 · 0 评论 -
离线+单调栈二分 CF 2009G2 - Yunli‘s Subarray Queries (hard version)
那么答案就是 sum{min[R::]} - sum{min[st[j - 1].r::]} - (st[j].r - R) * st[j].v。单调栈维护三元组 (r, v, s) 分别代表 最小操作次数为 v 的长度为 k 的子数组最靠右的左端点下标。对于每个查询 (L, R) 我们在单调栈上二分出 从栈顶到栈底第一个 R <= r 的 三元组的位置 j。对于一个查询(l, r)而言,f(i, r) 随着 i 的增加 而单调递减。s 为 sum{ min[r, n - k - 1] },即后缀和。原创 2024-11-08 09:53:34 · 280 阅读 · 0 评论 -
二分,CF 2036 G - Library of Magic
这道题没时间调了,有点可惜没能AK原创 2024-11-03 01:19:22 · 461 阅读 · 0 评论 -
最大权闭合图,CF 2026E - Best Subsequence
没开E血亏,怎么还有网络流的原创 2024-10-29 18:25:50 · 471 阅读 · 0 评论 -
构造+置换环,CF 1983D - Swap Dilemma
同时对a 施加 swap(a[0], a[1]),那么如果a 和 b 能都变相等,即升序排列,那么二者的逆序对的奇偶性应该相同。考虑一个数组变化的同时另一个数组也变化太过于复杂,我们考虑先将数组a 经过交换变为升序。我们考虑 每次对 b 施加相邻元素交换, 来一步步消除逆序对。时间复杂度: O(NlogN)空间复杂度:O(N)每次交换,逆序对的奇偶性翻转,置换环的奇偶性呢?对于排列而言,我们可以O(N)求出置换环的数目。考虑相邻元素在一个环:那么将分裂成两个环。考虑相邻元素在两个环:那么两个环将合并。原创 2024-10-28 21:25:23 · 292 阅读 · 0 评论 -
最短路,CF2024 D - Skipping
上面有一个可以优化的地方就是 对于第一种边,我们 只对于 b[i] > i 的情况连边,因为如果 b[i] <= i,那我们就没必要skip了,完全可以一路答题答过去。我们发现如果我们是从 i 一路回退的,那么得分就是 acc[i] - cost[i],cost[i] 是 一路跳到 i,在 [0, i - 1] 上所损失的代价。我们可以选择跳到 [0, b[i]] 的 某个题,也可以选择从这个点拿取 a[i] 的分数然后往回跳到某个题。我们也可以连出 i -> i - 1 的 权值为 0 的有向边。原创 2024-10-26 19:33:30 · 314 阅读 · 0 评论 -
思维+差分,CF 1884C - Medium Design
以mii = 0为例,我们对于所有左端点不为0的线段按左右端点双关键字排序,跑差分。也就是说,对于所有的包含 mai 的线段,我们拿进来不会使得答案变差。我们按照 mii 在左端 和 右端 的情况分别计算,求最值即可。时间复杂度: O(nlogn)空间复杂度:O(n)那么我们说明 最优解 的 mii 一定在 两端。同时包含 mai,mii 的线段我们可以不拿。如果 该线段不包含 mii,答案会 + 1。维护被覆盖次数最多的点的次数,维护最值即可。如果 该线段包含 mii,答案不会变大。原创 2024-10-23 17:28:44 · 276 阅读 · 0 评论 -
思维+构造,CF 1936A - Bitwise Operation Wizard
注意力什么时候才能提升啊原创 2024-10-19 12:08:18 · 422 阅读 · 0 评论 -
数位dp,CF 914C - Travelling Salesman and Special Numbers
所以我们只需计算出 [0, 1000] 的 f(),然后 对于 f(x) = k - 1的 x,我们找 [0, n] 之内 有多少数的pcnt = x,这件事情可以用数位dp轻松解决。我们注意到 虽然 n 很大,但是 对于 f(x) = k 的数字,其递推都是由 f(pcnt(x)) 转移,而pcnt(x) 很小,不超过1000。具体实现中,f() 我们可以初始化 f[0] = 1,从而原来的找 f(x) = k - 1 就 变为了 找 f(x) = k。那么 f(x) = f(pcnt(x)) + 1。原创 2024-10-18 23:58:11 · 406 阅读 · 0 评论 -
思维,CF 1980E - Permutation of Rows and Columns
我们记录 a、b中元素的行号列号rowa[] cola[] rowb[] colb[],然后 建立 str[], stc[]那么我们发现 a 能变成 b 当且仅当 a 中 任意元素 x 所在行列的集合 和 b 中元素所在行列的集合相同。显然,如果合法,那么 每个 str[i] stc[i] 的 size 都不大于1。时间复杂度: O(NM logn(N + M))空间复杂度:O(NM)str[rowa[x]] 为 所有 rowb[x] 的集合。str[cola[x]] 为 所有 colb[x] 的集合。原创 2024-10-15 13:01:46 · 322 阅读 · 0 评论 -
递推,CF 1957C - How Does the Rook Move?
如果选其他的(1, x) / (x, 1) x > 1,那么会扣掉一行一列,问题等价于 (n - 2) * (n - 2)的网格的方案数。f(i) = f(i - 1) + (2i - 2) * f(i - 2),2i - 2是第一行第一列除去 (1, 1) 剩下的格子数目。如果选(1, 1),那么问题等价于 (n - 1) * (n - 1) 网格的方案数。对于初始的 k 个操作,如果是对角线,那么n-1,否则n-2,然后输出f[n] 即可。时间复杂度: O(N)空间复杂度:O(N)原创 2024-10-12 22:29:12 · 406 阅读 · 0 评论 -
贪心+dfs,CF 1975D - Paint the Tree
dis(a, u) 我们可以树剖,maxd(u)我们可以换根dp,是可行的,然后可能要注意一下因为A先走B后走,dis(a, u) 和 dis(u, b) 我们注意一下corner case。不过我们注意到,最终答案的形式为:2n - 2 - maxd(u) + dis,这里的dis是二者在u相遇所需步数。那么对于一个相遇节点u,答案为 dis(a, u) + dis(u, b) + 2n-2 - maxd(u)我们从树中一点出发,遍历整颗树最后回到这个点的最小步数:2n - 2,即边数*2。原创 2024-10-12 16:18:31 · 550 阅读 · 0 评论 -
贪心,CF 865B - Ordering Pizza
不会同时 1<->2,不然的话我们总能取消1->2 或者 2->1 来减少代价。如果我们不考虑披萨数目的限制,我们贪心的为每个人分配最优披萨,会有什么结果?时间复杂度:O(NlogN) 空间复杂度:O(NlogN)如果买多了,最多调整 部分人 1->2 或者 2->1。那么对于两种方案,不管调谁,都去调代价最小的即可。原创 2024-10-09 22:14:38 · 446 阅读 · 0 评论 -
枚举+二分,CF 325B - Stadium and Games
那么有 m * (2^i - 1) + (m - 1) * m / 2 = n。除2,除2,除2 ……=> 变为 奇数m,m * (m - 1) / 2。时间复杂度: O(log^2 n)空间复杂度:O(1)考虑 一个可能的初始队伍数目 num 的 变化历程。因为指数增长很快,2^60 都已经超过1E18了。而一旦 i 固定,式子关于 m 就是单调递增的。假如除了 i 次2,变为奇数m。我们发现合法的 i 其实很少。于是想到 枚举 i,二分 m。原创 2024-10-09 21:24:53 · 388 阅读 · 0 评论 -
01背包,CF 1974E - Money Buys Happiness
每个商品选或不选,我们的钱有限,这就相当于一个以幸福度为容量,钱为价值的01背包。定义状态f(i, j)为 前 i 个物品,获得 j 幸福度,剩下的最多的钱。那么 f(i, j) = max(f(i - 1, j - h) - c)根据题意,我们每月结束,都要对当前合法的 f(i, j) 加上 x。时间复杂度: O(MH)空间复杂度:O(MH)问我们能够到达的最大幸福度。原创 2024-10-09 20:17:53 · 356 阅读 · 0 评论 -
差分,CF 558D - Guess Your Way Out! II
那么 该祖先对应的叶子节点的区间为 [l << (h - i), (r + 1) << (h - i))对于 每个查询,第 i 层 祖先的 区间如果真的在 [l, r] 内。如果 ans = 0,那么取补集,同样可以得到一个出口所在区间。被覆盖 q 次的编号如果只有一个,那么我们得到的答案。时间复杂度: O(qlogq)空间复杂度:O(q)如果 > 1,那么说明某次查询有问题。每个询问的信息都做完差分后,我们求和。这样我们得到了出口所在的一个区间。如果 = 0,那么信息不足。原创 2024-10-08 22:06:25 · 325 阅读 · 0 评论 -
二分+滑窗,CF 1208B - Uniqueness
如果 mp 的 size 等于 n - (r - l + 1),那么次数合法,我们尝试右收缩左边界。观察单调性:对于合法的删除区间 [l, r] r 右移,l 要么右移要么不动,一定不左移。只要收缩过程中 n - (r - l + 1) <= m,我们就返回true。我们 枚举r,维护l,哈希表mp 存储 [l, r] 外元素出现次数。时间复杂度: O(NlogN)空间复杂度:O(N)二分删除区间的长度 x。原创 2024-10-08 20:37:13 · 393 阅读 · 0 评论 -
二分,CF1624F - Interacdive Problem
在交互的过程中,x会变,但是初始的x0只有一个,由于交互是我们控制,所以x0的变化的值我们也已知。我们记 交互过程中累加值为add,我们只要求出最初的x0,那么答案就是 x0 + add。如果 query(q) > last (last 为 上一次交互值),说明二分小了。时间复杂度: O(logn)空间复杂度:O(1)令 q = n - (x + add) % n。相应的收缩区间并且累加 add 即可。闭区间二分 [1, n - 1]原创 2024-10-08 10:12:28 · 257 阅读 · 0 评论 -
递推+模拟,CF 748E - Santa Claus and Tangerines
上述递推的过程其实是 不断模拟的过程,随着我们答案的限制越来越小,原来不能划分的集合逐渐能够划分,贡献随之累加到 cur。如果 x 是答案,那么 能够分成的 size > x 的 集合 的数目 >= k。我们记 cnt[x] 为 能够划分 size = x 的集合的数目。然后倒序递推,维护一个cur,代表当前 >= i 的 集合的数目。我们维护cnt[],cnt 初始为 a[] 中的元素计数数组。首先 cur += cnt[i],即初始的 i 的数目。如果 i >= k,我们输出 i 即可。原创 2024-10-07 16:46:01 · 310 阅读 · 0 评论 -
思维+数论,CF 922C - Cave Painting
我们发现 n mod 1 = 0,如果 n mod 2!= n mod 1,那么 n mod 2 = 1。那么 n + 1 mod 1 = n + 1 mod 2 = ... n + 1 mod k = 0。我们从 1开始判断,只要有 n % i!= i - 1我们就输出No。而 我们发现 43!> 1E18,所以合法的 k 不会很大。时间复杂度: O(1)空间复杂度:O(1)以此类推 n mod k = k - 1。原创 2024-10-07 16:09:01 · 395 阅读 · 0 评论 -
前缀和+思维,CF 1984C2 - Magnitude (Hard Version)
否则,答案为 Σ 2^{n - i - 1 - posi},其中 sum[i] == min,posi 为 sum[0, i] 中 >= 0 的 i 的数目。如果我们通过多次操作2使得值变大,那么我们只需保留最后一次操作2仍然能得到最大值。如果min >= 0,那么操作1、2可以随便取,答案为 2^n。我们要得到最大值,执行操作2如果能让值变大,说明当前值为负数。C1 是只要求求最值,通过C1 我们知道 操作2最多。时间复杂度: O(N)空间复杂度:O(N)那么我们预先求出最小前缀和min。原创 2024-10-03 17:56:09 · 465 阅读 · 0 评论 -
试填+组合数学,CF 1648C - Tyler and Strings
那么对于L,它的贡献就是 cnt * fac(n - L - 1) / c0!cnt 代表 当前可用的 < t[L + 1] 的字符数,cnt 可以通过树状数组来获取。那么 第 L + 1位必须小于 t[L + 1],剩下的可以随便填。ci 分别代表 字符 i 的出现次数,因为会有重复所以要除去。时间复杂度: O(nlogn)空间复杂度:O(n)考虑枚举相同前缀的长度 L。原创 2024-09-29 17:23:11 · 428 阅读 · 0 评论 -
构造+bfs,CF 761E - Dasha and Puzzle
第二层的点分别向临界点伸边,每条边长度为 2^27,只要方向不往回走,就不会交叉。我们像玩贪吃蛇那样蛇形顺时针内卷的走,如何保证走n - 1次得到的边都不交叉?从0开始bfs 往外向邻接点伸边,每条边长度为 2^28。注意到 平面很大——1e18,而点数 & 边数很小。时间复杂度: O(N)空间复杂度:O(N)我们可以让第一根很长,后面依次减半。如果一个点的度 > 4,那么无解。原创 2024-09-27 13:19:11 · 492 阅读 · 0 评论 -
调和级数枚举+前缀和,CF 731F - Video Cards
然后枚举 x, 2x, 3x....,累加 (acc[kx + x - 1] - acc[kx]) * kx 的和。我们似乎只需要知道 [a * k, a * (k + 1) - 1) 内的数的个数就能计算这个区间内的数的贡献。考虑暴力的想法:从小到大枚举leading,然后暴力计算后面的数 x - x mod a 的和。预处理前缀和 acc[i] 代表 [0, i] 内的数字个数。时间复杂度: O(NlogN)空间复杂度:O(N)我们发现 x - x mod a = a * k。原创 2024-09-27 11:54:55 · 396 阅读 · 0 评论 -
思维+贪心,CF 1210B - Marcin and Training Camp
然后遍历剩下的数字 x,如果集合中存在某个数字y 满足 x & y = x,我们就把x 拿进集合。所以,我们先将所有 出现次数大于1 的数拿进集合(升序排序,去重即可)考虑一个数 x 不会比集合内所有数都强,可以注意到什么?否则,x 和 每个数相比总有对方没有的,那么就没办法了。时间复杂度: O(nlogn)空间复杂度:O(n)一定有一个数 y 满足 x & y = x。原创 2024-09-27 10:52:22 · 458 阅读 · 0 评论 -
思维+最小生成树,CF 436C - Dungeons and Candies
假如我们把数据当成节点,每个节点向其前驱连边,我们会得到一棵 k + 1个节点的树。每个数据的前驱是唯一的,对于直接传输的数据我们定义其前驱为虚拟节点。每个节点和其前驱的边权即该节点传输的代价。那么建图然后求最小生成树即可。原创 2024-09-26 23:25:01 · 366 阅读 · 0 评论 -
前后缀分解+贪心,CF 762C - Two strings
那么我们需要删除的最短长度就是 min{ suf[i + 1] - pre[i] - 1 }去除掉b的一个子串后,b剩下的前缀和后缀一定分别是a的前缀和后缀的子序列。suf[i] 代表 a[i::] 能包含最长的 b[suf[i]::]pre[] 代表 a[:i] 能包含的最长的 b[:pre[i]]本题要输出方案,那么维护下前缀长度和后缀起始位置即可。构建长度为 n 的两个数组 pre 和 suf。时间复杂度: O(N)空间复杂度:O(N)原创 2024-09-26 20:45:02 · 492 阅读 · 0 评论 -
贪心+构造,CF 761D - Dasha and Very Difficult Problem
即 最小的构造为 l - p[i],次小的构造为 max(l - p[i] + 1, l - a[j])……如果我们知道 c,那么根据 c[i] = b[i] - a[i],我们相当于得到了 b[]以及每个元素的范围:[l - a[i], r - a[i]]时间复杂度: O(NlogN)空间复杂度:O(N)显然越小越好,这样上面的元素容错率越高。我们知道了 c 各个下标元素排名。那么我们贪心的从低往上构造。原创 2024-09-26 16:40:00 · 486 阅读 · 0 评论 -
线段树优化dp,CF 413E - Maze 2D
然后线段树维护的是区间内 (0, l) -> (0, r) (0, l) -> (1, r) (1, l) - >(0, r), (1, l) - > (1, r) 的最短竖移步数。考虑定义 f((li, l), (ri, r)) 为 (li, l) -> (ri, r) 最短路径的竖着走步数。(li, ri) 的可能取值有4个,我们可以作为线段树的节点信息。那么 f((li, l), (ri, r)) = min{对于(li, l) -> (ri, r)如果能到一定要横着走 r - l 步。原创 2024-09-21 23:56:58 · 356 阅读 · 0 评论 -
中位数贪心+分组,CF 433C - Ryouko‘s Memory Note
我们考虑分组—— vals[x] = { 所有x出现位置前后不为x 的值 }改变 x 只会影响所有值为 x 的下标 及其前后下标的贡献。时间复杂度: O(MlogM)空间复杂度:O(N + M)对于x,我们要把x调为何值最优呢?那么我们分组考虑维护最小值。vals[x]的中位数。原创 2024-09-17 16:31:38 · 317 阅读 · 0 评论 -
二分+构造,CF 1063C - Dwarves, Hats and Extrasensory Abilities
我们考虑开局往左下角或者右下角中的一个位置放一个,这里不妨放右上角即(1e9, 1e9)如果 color(x, x) == col(hi, hi) 那么收缩 hi = x。最终输出 (lo, hi) (hi, lo) 即正方形的主对角线。时间复杂度: O(log U)空间复杂度:O(1)二分x = (lo + hi) / 2。看到 30 和 1E9就往二分上想。这样保证左下右上一定不同。否则收缩lo = x。原创 2024-09-17 15:57:05 · 387 阅读 · 0 评论