随笔分类 -  题目来源-Codeforces

摘要:区间 DP。朴素做法是 O(n^5) 的。通过更巧妙的状态设计,可以做到 O(n^4)。本文将详细讲解这种巧妙的状态设计,并帮助读者感谢理解它的含义。 阅读全文
posted @ 2020-12-26 22:16 duyiblue 阅读(184) 评论(1) 推荐(1) 编辑
摘要:首先发现每个字母会对答案有一个贡献系数,是 1 或 -1。结论是,除了 n 的系数必须是 1,n - 1 的系数必须是 -1,其他数的系数可以任意选择。于是问题转化为选择系数,使得和为 T。可以从大到小贪心。本文将证明其正确性。 阅读全文
posted @ 2020-12-24 14:16 duyiblue 阅读(334) 评论(1) 推荐(2) 编辑
摘要:每个初始时的格子会唯一对应一个最终的格子,于是拆开考虑每个格子的贡献。转化为对 n^2 个三元组,分别进行一样的操作。此时的操作是可以合并的。遍历 m 个操作,预处理出:任意一个初始三元组在被操作后会产生什么变化。然后将这个变化分别作用于所有初始三元组即可。 阅读全文
posted @ 2020-12-20 15:20 duyiblue 阅读(452) 评论(0) 推荐(1) 编辑
摘要:做 KMP 后,从 fail[x] 向 x 连边,得到一个有根树森林。用树链剖分优化暴力跳 border 的过程,转化为一个序列上的数据结构问题。可以离线,进一步转化为静态的区间覆盖和区间最小值查询问题。 阅读全文
posted @ 2020-12-16 22:06 duyiblue 阅读(319) 评论(0) 推荐(2) 编辑
摘要:发现可能出现的 42 的幂很少。如果只有操作 3,我们可以暴力 while,用线段树修改,每个位置只会被更新 log_{42}(maxValue) 次,总时间复杂度 O((n + q) * log_{42}(maxValue) * log_{2}(n))。在有操作 2 时,每个位置上数值不再单调增加,会影响前面的复杂度分析。此时引入一种懒惰状态,表示数值等于它后面第一个非懒惰状态的值。在操作 2 时,只修改 r 位置,并把 [l, r - 1] 置为懒惰状态。因为每次只需要增加 O(1) 个非懒惰状态,时间复杂度正确。 阅读全文
posted @ 2020-12-15 17:19 duyiblue 阅读(350) 评论(0) 推荐(0) 编辑
摘要:分析问题性质,容易得到一个 O(n^2) 做法。考虑对每个 Alice 的起点二分答案。换成整体二分,每次建虚树,在虚树上树形 DP,即可做到 O(n log^2 n)。注意要判断一个节点到 Alice 和 Bob 距离相等的情况,比较复杂。 阅读全文
posted @ 2020-11-25 21:03 duyiblue 阅读(475) 评论(1) 推荐(1) 编辑
摘要:一个结论是,不存在大小大于 2 的环。于是我们只需要保证图连通即可。从高到低考虑每一位,把数分成当前位为 0 的集合和当前位为 1 的集合,则为保证连通,必须有至少一个集合,大小小于 2。枚举删哪个集合,然后递归即可。本质是在 Trie 树上树形 DP。 阅读全文
posted @ 2020-11-19 22:06 duyiblue 阅读(543) 评论(4) 推荐(2) 编辑
摘要:考虑序列里唯一的、出现次数最多的数 x。结论:最长的好的子段,一定满足,x 是其中出现次数最多的数之一。然后可以枚举另一个出现次数最多的数 y。把 x, y 分别看成 1, -1,其他数看成 0,则问题转化为求最长的、和为 0 的子段,这很简单。在 D2 里,根据出现次数最多的元素的出现次数,进行根号分治,出现次数大时,可能的值就少,可以套用前一种方法。出现次数小时,可以枚举出现次数,做 two pointers 阅读全文
posted @ 2020-11-19 21:01 duyiblue 阅读(1078) 评论(0) 推荐(5) 编辑
摘要:分 n 为奇数和偶数两种情况。奇数时,容易用人类智慧构造出一种方案。偶数时,考虑何时有解,何时无解。发现一次操作不会改变所有数的异或和。那么,有解的必要条件是,所有数异或和为 0。发现此时,随便拿出一个数,对剩下 n - 1 个数按奇数的方法构造即可。 阅读全文
posted @ 2020-11-19 19:17 duyiblue 阅读(526) 评论(1) 推荐(2) 编辑
摘要:运用唯一分解定理,考虑 x 的质因数构成。对小于等于 sqrt(n) 的质数暴力查询。对大于 sqrt(n) 的质数,可以有两种方法。若小质数部分 x_small > 1,则对每个大质数 p,查询 p * x_small 是否还在集合里。若 x_small = 1,对大质数序列分块。先确定 x 在哪块里,再暴力查询。 阅读全文
posted @ 2020-11-12 13:34 duyiblue 阅读(444) 评论(2) 推荐(1) 编辑
摘要:考虑把 DAG 分层,用状压 DP 来实现这个过程。每次转移增加一层,必须满足所有能到达新层的点,都在原点集里出现过。把每条边的代价,分摊到它跨过的每一层里。也就是每次转移,代价是:所有起点已经在 S 里,终点不在 S 里的边的边权之和。 阅读全文
posted @ 2020-11-09 22:07 duyiblue 阅读(791) 评论(0) 推荐(4) 编辑
摘要:可以将 a 序列排序。枚举 p,q 上每个位置 i 对答案的贡献。枚举 p,q 上第 i 位的元素分别为 aj, ak。根据 j,k 的大小关系分类讨论一下,用组合数算出方案数,时间复杂度 O(n^3)。单独枚举 j 和 k,分别计算贡献(正的或负的,需要分类讨论一下),即可做到 O(n^2)。然后拿着 O(n^2) 的式子,把它化成卷积的形式,就能得到 O(n log n) 做法,可以通过本题。 阅读全文
posted @ 2020-11-01 22:40 duyiblue 阅读(359) 评论(1) 推荐(1) 编辑
摘要:题目来源:Codeforces,#678,Codeforces Round #678 (Div. 2),CF1436;CF1436E Complicated Computations,CF1436F Sum Over Subsets。 CF1436E Complicated Computations 阅读全文
posted @ 2020-10-28 23:49 duyiblue 阅读(230) 评论(0) 推荐(0) 编辑
摘要:不会删边,考虑倒序操作,删边变加边。但操作 1 又只能正序进行。所以考虑倒序加边建出重构树,然后正序处理操作 1。用线段树维护重构树的 dfs 序即可。 阅读全文
posted @ 2020-09-30 11:39 duyiblue 阅读(253) 评论(0) 推荐(1) 编辑
摘要:树形DP。转移时将儿子按 h 的大小关系分成三类。枚举和 h[u] 相等的儿子里,有几个定向为向上,则可以贪心地取 dp[v][0] - dp[v][1] 前若干大的。 阅读全文
posted @ 2020-09-30 11:11 duyiblue 阅读(328) 评论(1) 推荐(0) 编辑
摘要:转化为最小化每一段的代价之和。设 dp[i][j][k] 表示考虑了前 i 个位置,第 i 个位置放了 1,用了 j 次操作,前 i 个位置共放了 k 个 1,此时的最小代价和。转移时枚举下一个 1 的位置,时间复杂度 O(n^5),可以用斜率优化优化到 O(n^4 log n) 阅读全文
posted @ 2020-09-25 11:49 duyiblue 阅读(635) 评论(6) 推荐(7) 编辑
摘要:枚举x。一个x可行当且仅当,0,1,...,2^x-1都能被表示为S的一个子集的异或和。可以对S建线性基判断。然后每个值会对应一个S的子集,也就是对应一个S的线性基的子集。我们要构造一种方案,把2^x个S的线性基的子集排列,使得相邻两数只有一个二进制位不同。可以用格雷码 阅读全文
posted @ 2020-09-09 17:10 duyiblue 阅读(213) 评论(1) 推荐(0) 编辑
摘要:n为偶数时先手必胜。n为奇数时,所有数之和mod 2n=n,所以只需要找出一个和是n的倍数的方案即可。容易证明,一定存在一种方案,把mod n=0,1,2,...,n-1的数各选一次 阅读全文
posted @ 2020-09-07 12:31 duyiblue 阅读(353) 评论(3) 推荐(1) 编辑
摘要:可以证明,我们总能通过巧妙地安排删除顺序,使得所有“理论上能被删除的数”都被删掉。那么,对于前i个数里最多能删多少个,容易得到递推式 f(i) = f(i-1) + [i>=a(i) and f(i-1)>=i-a(i)]。区间询问。我们对每个i,预处理出使得它能被删掉时,前面最多ban掉多少个数。预处理可以二分+主席树求。询问可以直接在主席树上查询。 阅读全文
posted @ 2020-09-07 10:48 duyiblue 阅读(712) 评论(2) 推荐(0) 编辑