给定一个固定的序列,有多次查询;每次查询某个区间的元素集合信息(去除重复值项)。
由于是序列是固定的,故可以对所有查询进行离线处理,对查询按照区间右端点从小到大排序;按此顺序处理查询,在处理查询之前维护好序列中各个值在本次查询的右端点之前最后出现的位置,我们只在最后出现的这个值的位置保留这个值,之前的位置都删除;这样区间查询的时候就不会计算到重复的值项。用map映射某个值最后出现的位置,用树状数组或者线段树维护区间信息即可。
另外如果觉得map运行速度太慢,可以尝试一种离散化处理的方法(当然会不会比map快不好说,视具体情况而定):
for (int i=1;i<=n;i++) {
scanf("%d", &a[i]);
b[i-1] = a[i]; //b数组最终用来存放不重复的数值
}
sort(b,b+n);
int nb = unique(b,b+n)-b;
for (int i=1;i<=n;i++){
a[i] = lower_bound(b,b+nb,a[i])-b;
//将原来数组元素赋值成该元素在b数组中的位置,这个位置当作key来用
}
例题1
HDU-3333
求某个区间的不重复元素的和。
#include
#include
#include
#include
例题2
Codeforces 703D
求某个区间不重复元素的异或和,跟上一题一样的处理方法,利用异或的性质即可。
#include
#include