随笔分类 - 算法-分块
摘要:有关“序列、区间里、数值的出现次数”的问题,一般都要想到用莫队来维护。莫队后,往往就是要维护一个序列,支持单点修改,然后回答各种各样的询问。因为外层套了莫队,所以需要 O(1) 的单点修改,而询问则可以较慢。一般的数据结构(如线段树、平衡树),修改和查询都是 O(log n) 的,往往难以胜任。此时有一些巧妙的解决方法。
阅读全文
摘要:根号分治。对序列里小于 sqrt(n) 的数和大于等于 sqrt(n) 的数,用两种不同的 DP,分别计算出方案数,最后卷起来,得到答案。
阅读全文
摘要:考虑序列里唯一的、出现次数最多的数 x。结论:最长的好的子段,一定满足,x 是其中出现次数最多的数之一。然后可以枚举另一个出现次数最多的数 y。把 x, y 分别看成 1, -1,其他数看成 0,则问题转化为求最长的、和为 0 的子段,这很简单。在 D2 里,根据出现次数最多的元素的出现次数,进行根号分治,出现次数大时,可能的值就少,可以套用前一种方法。出现次数小时,可以枚举出现次数,做 two pointers
阅读全文
摘要:运用唯一分解定理,考虑 x 的质因数构成。对小于等于 sqrt(n) 的质数暴力查询。对大于 sqrt(n) 的质数,可以有两种方法。若小质数部分 x_small > 1,则对每个大质数 p,查询 p * x_small 是否还在集合里。若 x_small = 1,对大质数序列分块。先确定 x 在哪块里,再暴力查询。
阅读全文
摘要:题目来源:Codeforces,#678,Codeforces Round #678 (Div. 2),CF1436;CF1436E Complicated Computations,CF1436F Sum Over Subsets。 CF1436E Complicated Computations
阅读全文
摘要:把点分为大点和小点。修改时,如果是小点,则暴力更新所有邻居。查询时,枚举邻居中的大点,计算影响。一共需要O((n+q)*sqrt(n))次修改操作,O(q)次查询操作,考虑怎么维护每个点的集合,来支持这些操作。如果用动态开点线段树维护,则修改是O(log a),查询是O(1)的,不太合适。发现mex的值域只有deg(u),所以可以用数组记录每个值的出现次数,O(1)修改。对值域分块,O(sqrt(n))查询
阅读全文
摘要:静态问题,可以结合子集枚举、大力递归(递归的边界,需要用高维前缀和预处理出来)这两种暴力,单次修改或查询的复杂度是O(2^{n/2})的。高维前缀和,可以等所有修改完成后,用fwt求出。非静态的问题,只需要对操作分块,不同块之间相当于是静态问题,块内的贡献可以直接枚举每个修改,计算出来。
阅读全文