这题和我之前做的mex原理等价
比赛的时候虚树开的太长了
爆内存的时候返回的wa
我一直以为是代码写的有问题
其实权值线段树的长开n+1就够了
代码只有39行
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
struct ContinueTree{
int l,r,Min,sum;
#define l(x) Tree[x].l
#define r(x) Tree[x].r
#define Min(x) Tree[x].Min
#define sum(x) Tree[x].sum
}Tree[25*N];
int tot=0,to=0,A[N],R[N],RR[N];
void Insert(int &x,int l,int r,int p,int v){
Tree[++tot]=Tree[x];x=tot;sum(x)++;
if(l==r){Min(x)=v;return;}
int mid=(l+r)/2;
if(p<=mid) Insert(l(x),l,mid,p,v);
else Insert(r(x),mid+1,r,p,v);
Min(x)=min(Min(l(x)),Min(r(x)));
}
int Query(int x,int y,int l,int r,int v){
if(l==r) return sum(y)-sum(x);
int mid=(l+r)/2;
if(Min(l(y))<v) return Query(l(x),l(y),l,mid,v);
else return Query(r(x),r(y),mid+1,r,v)+sum(l(y))-sum(l(x));
}
int main(){
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&A[i]);
Insert(R[i]=R[i-1],1,n+1,A[i]>n?n+1:A[i],i);
}
scanf("%d",&m);
while(m--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",r-l+1-Query(R[l-1],R[r],1,n+1,l));
}
}