
树状数组
Lynstery
一只蒟蒻
展开
-
[离线+树状数组 || 主席树]BZOJ1878: [SDOI2009]HH的项链
题意给出一个n个数的数列。m次询问,每次求[L,R]区间中包含了多少种不同的数字。 (N ≤ 50000,M ≤ 200000)题解水题,解法很多。 我这里主要讲两种解法,实际上主要思想都差不多。 对于一个区间中的若干个相同数字,我们只关注最先出现的那个即可, 然后就可以乱搞了。离线+树状数组:我们建一个jump表,jump[i]表示在i之后第一个值与i相同的位置。 离线一下,从小到大枚举原创 2017-04-25 07:51:45 · 775 阅读 · 0 评论 -
[莫比乌斯反演+数状数组] BZOJ3529: [Sdoi2014]数表
题意有一张N×m的数表,其第i行第j列(1 <=i <=n,1 <=j <=m)的数值为 能同时整除i和j的所有自然数之和。给定a,计算数表中不大于a的数之和。 多次询问,输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据。 n,m,Q <=10^5 题解设g(i)为gcd(x,y)等于i的数对个数(x<=n,y<=m),原创 2017-07-03 11:49:04 · 413 阅读 · 2 评论 -
[离线+树状数组] HDU5869 Different GCD Subarray Query
对于这种询问有多少个不同的东西,有比较套路的方法是把询问离线,然后同种元素的贡献记在最近的位置上。比如 BZOJ1878 [SDOI2009]HH的项链 这题也是类似的做法,只是一个点上的元素不是1个而是log V个。所以就 O(nlog2n)O(nlog^2n)#include<cstdio>#include<cstring>#include<vector>#include<algorit原创 2017-09-19 18:13:29 · 459 阅读 · 0 评论 -
[数位DP] ZROI 2017 提高3 T1 树状数组
不错的题。这个应该从二进制角度考虑。我们知道树状数组每次就是把二进制最末尾的 11 去掉。那么考虑对 rr 和 l−1l-1 分别加 11 减 11 后,有值的节点个数即 cnt(r)+cnt(l−1)−2∗cnt(prefix(r,l−1))cnt(r)+cnt(l-1)-2*cnt(prefix(r,l-1)) 。其中cntcnt 是二进制下 11 的个数,prefixprefix 是公共前缀。原创 2017-10-07 12:54:13 · 594 阅读 · 0 评论 -
[杂题 树状数组] 51Nod1681 公共祖先
不错的题,思路很套路。考虑求的答案是 ∑i,j∑k[k在两棵树中都是i,j的祖先]\sum_{i,j} \sum_k [k在两棵树中都是i,j的祖先] 改变枚举顺序,设 Son1(x)Son_1(x) 表示第一棵树中以x为根的子树的点集,答案就变成: ∑k(|Son1(k)∩Son2(k)|2)\sum_k { | Son_1(k) \cap Son_2(k) |\choose 2} 这个原创 2017-10-30 07:47:34 · 379 阅读 · 0 评论 -
[杂题 离散 扫描线] BZOJ1227: [SDOI2009]虔诚的墓主人
不难的题。 考虑一个空的点的贡献是一个组合数的形式,即答案为 ∑(leftK)(rightK)(upK)(downK) \sum {left \choose K }{right \choose K }{up \choose K }{down \choose K } 怎么求呢? 显然先离散,只需考虑离散后的网格上的点。 对于每一行,可以考虑扫过取求两个实点中间空点的贡献,每一段的贡献是(le原创 2017-10-30 18:43:59 · 335 阅读 · 0 评论