分块 分块,就是将原序列处理成各个小块,目的是尽量地达到处理和询问之间的平衡 常用于:原本O(1)修改O(n)查询或O(n)修改O(1)查询优化成O(sqrt(n))修改O(sqrt(n))查询,或者看起来很像线段树(树状数组)但是又不好维护的。 有些专门卡空间的题可以用分块做(lca)。 能用分块就尽量不用树套树。 分块...
思路:这题可用主席树查询历史版本的方法做,感觉这个比较容易想到...但是主席树不太会用 其次可以用莫队分块的方法暴力过,再来就是使用树状数组维护不同数量的前缀和了,如果不使用离散化直接用map的话还会TLE... 通过维护当前位置上的数所记录的下标最靠右(即最近一次出现的位置),一边维护数量的前缀和,一边检查是否...
B. Light bulbs 题意: N 个 灯泡(编号 0 ~ N-1) M 次操作(初始灯都是关的) 每次操作 给 2个数 L, R,把[L, R]区间内的开关翻转 求 M次操作后 有多少灯开着 题解: 暴力 O(NT) 复杂度到达1e9 TLE 线段树 树状数组 O(TN*logn)也会超时 这个题内存也很小,对M次操作进行处理。 先对m组数...
树状数组:3542ms 线段树:4531ms(用递归就是慢呀) 分块:6997ms 时间复杂度 O(nlogn)O(nlogn) 参考文献 无 C++ 代码 树状数组: 为此我格式化一下代码,让大家方便阅读 #include<bits/stdc++.h> #define lowbit(x) (x & -x) using namespace std; typedef long long LL; const LL N = 2e5 + 10;...
求的是 如果a[i]小于等于0的话其实可以全局加上某一个数字,变成正的,要不然szsz干不了他 像我这样智商不够归并排序的蒟蒻只能靠数据结构来凑啦
这个用树状数组维护,但是权值太大需要离散化。 这里的离散化是用新数组排序再二分查找,比用结构体排两次方便一些。 然后需要多加一个0表示s[0]。 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
题解:这是一道万能题,树状数组 || 主席树 || 线段树合并 || 莫队套分块 || 线段树 都可以写。。记得离散化 线段树合并版: 1#include<cstdio>2#include<cstring>3#include<iostream>4#include<algorithm>5usingnamespacestd;6constintmaxn=(1e5)+50;7intN,num_edge=0,edge_head[maxn],W[maxn],lsh_...
Sample Input 5 3 3 2 1 4 7 Q 1 4 3 C 2 6 Q 2 5 3 Sample Output 3 6 HINT 20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。 Source 题解: 树状数组套主席树。程序中有注释。耐心看就看懂了。 View Code...
归并排序就不说了(我也没写过),一般是用树状数组做这个的吧~ 但是值域这么大开不下呀怎么办呀~当然是选择离散化了 比如我们可以这样: #definerep(i,n) for(register int i=1;i<=n;i++)intn,w[N],rak[N]; inlineboolcmp(inta,intb)
一开始就感觉有点像线段树,输入数据太大我们可以离线处理把数据离散化下,然后扔到线段树上,维护两个数组: sum: 区间数的值的和 num: 区间数的数量和 ,对于每次询问的first和second,我们找到第first个和第second个分别是哪两个数字, 如果两个数字不相同,那么就先算出分别取了多少个这两个数字,对于两个数字中间...