F.little w and Discretization
题意:找区间[l,r]内离散化后和原来的值不同大小的数的个数
思路:先求区间mex,同时记录区间有多少个数,再 用区间长度减去(区间内小于mex数的个数)
const int maxn=1e6+5;
int n,cnt,a[maxn],m,root[maxn],b[maxn],c[maxn];
struct node{
int l,r,val,he;
}tr[maxn<<4];
int update(int pre,int l,int r,int val,int pos){
int now=++cnt;
tr[now]=tr[pre];
tr[now].he++;
if(l==r){
tr[now].val=pos;
return now;
}
int mid=(l+r)>>1;
if(val<=mid)tr[now].l=update(tr[pre].l,l,mid,val,pos);
else tr[now].r=update(tr[pre].r,mid+1,r,val,pos);
tr[now].val=min(tr[tr[now].l].val,tr[tr[now].r].val);
return now;
}
int query(int now,int l,int r,int d){
if(l==r)return l;
int mid=(l+r)>>1;
if(tr[tr[now].l].val<d)return query(tr[now].l,l,mid,d);
return query(tr[now].r,mid+1,r,d);
}
int getsum(int pre,int now,int l,int r,int x,int y){
if(x<=l&&r<=y)return tr[now].he-tr[pre].he;
int mid=(l+r)>>1,ans=0;
if(x<=mid)ans+=getsum(tr[pre].l,tr[now].l,l,mid,x,y);
if(y>mid)ans+=getsum(tr[pre].r,tr[now].r,mid+1,r,x,y);
return ans;
}
int main(){
while(~scanf("%d",&n)){
cnt=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]>n)root[i]=root[i-1];
else root[i]=update(root[i-1],1,n,a[i],i);
}
scanf("%d",&m);
while(m--){
int l,r;
scanf("%d%d",&l,&r);
int d=query(root[r],1,n,l);
int he=getsum(root[l-1],root[r],1,n,1,d);
printf("%d\n",r-l+1-he);
}
}
}