怎么说呢 这种跟区间不同个数相关的题,如之和维护前缀和呢?
经典套路操作就是维护某个数最后出现的位置
然后不能被前缀和的思想束缚——这题就是直接查第R棵树的情况
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+15;
int tr[N],lc[N<<5],rc[N<<5],mn[N<<5];
int cnt;
void pushup(int k){
mn[k]=min(mn[lc[k]],mn[rc[k]]);
}
void insert(int &now,int pre,int l,int r,int k,int pos){
now=++cnt;
lc[now]=lc[pre];
rc[now]=rc[pre];
if(l==r){
mn[now]=pos;
return;
}
int mid=l+r>>1;
if(k<=mid)
insert(lc[now],lc[pre],l,mid,k,pos);
else
insert(rc[now],rc[pre],mid+1,r,k,pos);
pushup(now);
}
int query(int now,int l,int r,int x){
if(l==r)
return l;
if(mn[now]>=x)
return r+1;
int mid=l+r>>1;
if(mn[lc[now]]<x)
return query(lc[now],l,mid,x);
else
return query(rc[now],mid+1,r,x);
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){
int x;cin>>x;x++;
insert(tr[i],tr[i-1],1,N,x,i);
}
while(m--){
int l,r;cin>>l>>r;
cout<<query(tr[r],1,N,l)-1<<'\n';
}
}
ps这题其实完全不需要离散化,主席树尽可能的开大,我一开始开了16倍,结果显示我wa了4个点,开32倍就过了