对于主席树,只要注意一点就好了:
空间$nlogn+mlogn$
空间$nlogn+mlogn$
空间$nlogn+mlogn$
$qwq$
$WA$了好几次,最后下狠心将空间开大$40$倍就过了$qwq$
主席树这么吃空间,
把经常爆栈的本宝宝吓的不敢再写了$qwq$
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m; int a[1000010]; int t[1000010]; int x,y,k; int lc[4000010]; int rc[4000010]; int num[4000010]; int root[4000010]; int len,siz; void update(int pos,int &x,int l,int r,int val) { x=++siz; num[siz]=num[pos]+1; lc[siz]=lc[pos]; rc[siz]=rc[pos]; if(l==r) return ; int mid=l+r>>1; val<=mid?update(lc[pos],lc[siz],l,mid,val):update(rc[pos],rc[siz],mid+1,r,val); } int query(int x,int y,int l,int r,int val) { if(l==r) return t[l]; int mid=l+r>>1; return num[lc[y]]>=val+num[lc[x]]?query(lc[x],lc[y],l,mid,val):query(rc[x],rc[y],mid+1,r,val-num[lc[y]]+num[lc[x]]); } inline void discretization() { sort(t+1,t+n+1); len=unique(t+1,t+n+1)-t-1; for(int i=1;i<=n;i++) a[i]=lower_bound(t+1,t+len+1,a[i])-t, update(root[i-1],root[i],1,len,a[i]); return ; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]),t[i]=a[i]; discretization(); for(int i=1;i<=m;i++) scanf("%d%d%d",&x,&y,&k), printf("%d ",query(root[x-1],root[y],1,len,k)); return 0; }