例题:Codeforces 220B-Little Elephant and Array
题目大意:
题意:
给出一个长度为n的数组,有m个询问,每次询问给出一个区间,问这个区间内有多少个数x恰好出现x次
这种题的特点:
1、m次查询,可以离线处理。
一般以各查询区间的右端点排序,用扫描线在相关函数(区间历史值,差分序列)做修改。
2、运用差分序列。一般右端点固定,考虑之前区间,再右边的区间不影响,等到右端点移动时,再修改这个区间的信息。
3、由于扫描线,修改的值往往在要改的地方(及左右两个位置),属于单点修改,树状数组最快。
这题维护的特殊的差分序列 t [maxn] 数组画个表既可以表示。
相应修改对应下面代码
add(v[a[i]][len-a[i]],1);
if(len>a[i]) add(v[a[i]][len-a[i]-1],-2);
if(len>a[i]+1) add(v[a[i]][len-a[i]-2],1);
代码:
ll n,m,a[maxn],t[maxn],ans[maxn];
typedef pair<int,int>p;
vector<p>e[maxn];
ll lowbit(int x){
return x&(-x); }
void add(int i,ll v){
for(;i<=n;i+=lowbit(i)) t[i]+=v; }
ll ask(int i){
ll ans=0;
for(;i;i-=lowbit(i)) ans+=t[i];
return ans;
}
vector<int>v[maxn];
int main(){
n=read