随笔分类 -  题目来源-Codeforces

摘要:先考虑 k 是偶数的情况,此时 k 必须是 2n 的约数,且不能是 n 的约数,并且 k 要尽量小,所以令 k = 2 的 (n 里 2 的最高次数 + 1) 次方即可。若 k 还是太大,说明偶数无解,考虑奇数。此时有一个非常巧妙的想法:令 k2 = 2n / k。会发现这个 k2 一定是满足条件的。 阅读全文
posted @ 2022-04-10 13:17 duyiblue 阅读(110) 评论(0) 推荐(1) 编辑
摘要:首先,全局最大值一定是其中一个子序列的最大值,所以只需要考虑另一个子序列的最大值是几。根据这两个“最大值”,整个序列被划分为三段,前一段两个序列都递增,中间一增一减,第三段都递减。第一段和第三段可以用简单 DP 完成最优划分。中间段其实也可以用一个类似的 DP 来划分。DP 定义的关键是考虑与 i 不同的另一个子序列最后一个元素是几,转移时考虑 i 和 i - 1 在不在同一个序列中。 阅读全文
posted @ 2022-03-15 14:18 duyiblue 阅读(138) 评论(0) 推荐(1) 编辑
摘要:用总数减去不合法的排列数。考虑不合法的排列里的极长不合法段,那么不合法的排列可以分为两类:有两个极长不合法段的,或者有三个及以上极长不合法段的。对于前者,发现至少有一个不合法段是前缀或后缀,且数值为 1...k,可以递推求出其方案数(二次容斥)。对于后者,不合法段一定不相交。考虑用 DP 对齐进行划分,再用前面处理好的答案算出其排列方案数。 阅读全文
posted @ 2021-03-25 23:18 duyiblue 阅读(213) 评论(0) 推荐(1) 编辑
摘要:首先把问题转化为:有一个给定的数组 b[1...n],一个数 x,使得所有 (b[i] + x) 的二进制里 1 的个数之和最小。从低到高逐位 DP,发现要考虑上一位有没有进位,那么状态数是 2^n 的。进一步观察,因为每个数加的 x 是一样的,所以在这些低位上原数值越大,越有可能进位。所以状态里只需要记录有多少个数进位,然后把序列排个序,就知道具体是哪些数进位了 阅读全文
posted @ 2021-03-25 23:12 duyiblue 阅读(221) 评论(0) 推荐(0) 编辑
摘要:本文提供了两种解法。一种是硬核数据结构做法。将限制转化为一个几何问题(双矩形的交),用扫描线求解。第二种是巧妙的贪心,证明了如何选择 n1, n2 是最有可能有解的,于是在确定 n1, n2 后,直接进行二分图染色即可 阅读全文
posted @ 2021-03-16 17:37 duyiblue 阅读(210) 评论(1) 推荐(1) 编辑
摘要:以第一个关键节点为根。根据:v 在 x, y 的路径上,当且仅当 dis(v, x) + dis(v, y) = dis(x, y),可以确定每个关键点到根的路径。接下来按深度从小到大加入剩余的节点。只需要在已经确定的部分里为它找到一个父亲即可 阅读全文
posted @ 2021-03-15 13:09 duyiblue 阅读(244) 评论(2) 推荐(0) 编辑
摘要:用 bitset 支持操作 2,但操作 3 比较困难。考虑不是记录每个数的出现次数,而记录每个数的倍数的出现次数。这样操作 2,3 都可以轻松实现。回答询问时,把每个倍数乘以莫比乌斯函数,就能还原出答案 阅读全文
posted @ 2021-03-11 21:25 duyiblue 阅读(133) 评论(2) 推荐(0) 编辑
摘要:使用容斥原理解本题需要大量的分类讨论,故我们转而考虑不重不漏地计数。将约数按它在 A,B,C 哪几个里出现过,分为 7 类。枚举三元组里每个数的种类,则选择的方案数可以用一个组合数公式计算出来 阅读全文
posted @ 2021-02-27 10:35 duyiblue 阅读(173) 评论(0) 推荐(0) 编辑
摘要:考虑查询一段区间 [l,r] 里线段并的长度怎么做。可以枚举右端点,维护左端点的答案。同时对数轴上每个位置,记录最后一个覆盖到它的线段编号,用 set 维护数轴上的这些线段。加入一条新线段时,要更新答案,相当于对一段左端点的答案做区间加。回到本题,可以二分价值第 k 大的区间的价值,然后求价值大于等于 mid 的区间数量,做法和上面类似 阅读全文
posted @ 2021-02-15 16:38 duyiblue 阅读(907) 评论(1) 推荐(2) 编辑
摘要:考虑只划分一轮的情况。对于所有 k,发现划分为 k 块的方案数,要么是 0,要么是 1。对“有唯一一种划分方案”所需的条件稍作转化,就能求出每个 k 是否存在方案了。然后考虑不止划分一轮的情况,可以做一个简单的 DP。时间复杂度是调和级数。 阅读全文
posted @ 2021-02-14 17:50 duyiblue 阅读(279) 评论(1) 推荐(0) 编辑
摘要:两棵树上公共的边我们都不去动它。将它们缩起来。然后每次找一个叶子节点,拆掉它和父亲的边。发现一定能找到另一条边加上。可以用并查集维护 阅读全文
posted @ 2021-02-10 13:48 duyiblue 阅读(115) 评论(0) 推荐(0) 编辑
摘要:首先想到把 k/2 个元素分为一块,不同块里元素的去重,可以暴力枚举每一对块,将它们一起加入队列。搞一对块就清一次队列,有点浪费。考虑把块连成一张有向图,那么每次可以顺着图上的路径一直走。问题转化为将图划分为尽可能少的路径,使得每条边恰属于一条路径。发现扩充为完全图后,可以得到更优秀的划分方案。 阅读全文
posted @ 2021-02-03 21:31 duyiblue 阅读(318) 评论(0) 推荐(3) 编辑
摘要:对值域分块,每块内按原序列里的位置排序。查询时把每块内下标在 [l,r] 之间的提取出来,依次合并。问题转化为预处理出每块内的所有区间对应的集合。可以在值域上分治。每次把小于等于 mid 的元素和大于 mid 的元素,按原顺序分在两边,递归求解后,再把两边的答案合并。 阅读全文
posted @ 2021-02-03 01:06 duyiblue 阅读(218) 评论(0) 推荐(0) 编辑
摘要:记两次查询的节点分别为 a, b,两次查询得到的结果分别为 d1, d2。我们依次枚举 a, d1, b, d2。枚举 a, d1 后,对每个点 v,预处理出罪犯第二天来到点 v 的概率 p(v)。这样就能很方便地对一组 (a, d1, b, d2) 计算答案。发现对同一个 a,在所有 d1 下,p(v)!=0 的点 v 数量是 O(n) 的。所以这四重枚举的时间复杂度,实际是 O(n^3)。 阅读全文
posted @ 2021-01-29 22:28 duyiblue 阅读(179) 评论(0) 推荐(0) 编辑
摘要:先考虑期望的定义,发现不好计算。于是补集转化,发现转化后可以通过简单的树形 DP 解决。添加叶子时,只需要更新它祖先的 DP 值。并且在精度允许的范围内,我们只需要更新距离不超过某个阈值的祖先。 阅读全文
posted @ 2021-01-22 22:01 duyiblue 阅读(114) 评论(0) 推荐(0) 编辑
摘要:涉及到无穷大的概念,就可以抛弃一些传统的 DP 做法。使用数学的推导。本题的状态设计和转移方式,都是非常巧妙的。 阅读全文
posted @ 2021-01-19 12:49 duyiblue 阅读(269) 评论(0) 推荐(2) 编辑
摘要:考虑实现一个核心函数:求出某个后缀,花费不超过 c 时,字典序第 k 小的结果序列,的第一次操作。实现这个函数后,通过调用不超过 c 次该函数,可以求出答案。我们对后缀做一些预处理,就可以快速实现这个核心函数。预处理需要观察一些性质,然后用 deque 实现。 阅读全文
posted @ 2021-01-11 13:57 duyiblue 阅读(752) 评论(1) 推荐(5) 编辑
摘要:很神的数据结构题!!!先做前缀和等初步转化,可以变成关于两个序列、区间最大、最小值的问题。枚举 r,用单调栈维护出使其中一个序列合法所需要做的操作。对另一个序列,可以贪心地在区间端点处进行操作。找出最小的、合法的区间端点,可以在线段树上二分。但这个线段树维护的信息比较特殊,要用到类似于《楼房重建》这题里,log^2 线段树的技巧。 阅读全文
posted @ 2021-01-05 14:30 duyiblue 阅读(358) 评论(7) 推荐(3) 编辑
摘要:树形 DP。把第二维搬到线段树上,然后线段树合并。这是常见的套路(NOI2020 d1t2),但在本题里会 MLE。进一步优化,需要根据题目性质(有效 DP 值的单调性),将线段树改为 set,做启发式合并。 阅读全文
posted @ 2021-01-03 18:13 duyiblue 阅读(355) 评论(0) 推荐(1) 编辑
摘要:分情况讨论。枚举最终相遇的环,然后对其他环做个背包。用 CSP2019 d2t1 的套路设计 DP 状态,只记录二者的差值。 阅读全文
posted @ 2020-12-29 22:35 duyiblue 阅读(168) 评论(1) 推荐(0) 编辑