rt,本地没问题,但交上去WA了两个点,求助
#include <bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch&15);ch=getchar();}
return x*f;
}
const int N=2e5;
const int SIZE=N*64;
int n,m;
int arr[N];
int sta[N],top;
#define _L -0x3f3f3f3f
#define _R 0x3f3f3f3f
#define mid ((l+r)>>1)
namespace WST{
struct TREE{
int ls,rs,sum;
}tree[SIZE];
int CNT,rt[N];
inline void pushUp(int root){
tree[root].sum=tree[tree[root].ls].sum+tree[tree[root].rs].sum;
}
void update(int &root,int l,int r,int pos,int sum){
if(!root) root=++CNT;
if(l==r){tree[root].sum+=sum;return;}
pos<=mid?update(tree[root].ls,l,mid,pos,sum):update(tree[root].rs,mid+1,r,pos,sum);
pushUp(root);
}
int kth(int root,int l,int r,int k){
if(tree[root].sum<k) return -1;
if(l==r) return l;
return k<=tree[tree[root].ls].sum?kth(tree[root].ls,l,mid,k):kth(tree[root].rs,mid+1,r,k-tree[tree[root].ls].sum);
}
void merge(int &Address,int x,int y,int l,int r){
if(!x||!y){
Address=x|y;
return;
}
if(!Address) Address=++CNT;
if(l==r){
tree[Address].sum=tree[x].sum+tree[y].sum;
return;
}
merge(tree[Address].ls,tree[x].ls,tree[y].ls,l,mid);
merge(tree[Address].rs,tree[x].rs,tree[y].rs,mid+1,r);
pushUp(Address);
return;
}
}
struct TREE{
int ls,rs;
int val;//在权值线段树上的编号
}tree[N<<4];
int CNT,rootOfSegtree;
inline void pushUp(int root){
WST::merge(tree[root].val,tree[tree[root].ls].val,tree[tree[root].rs].val,_L,_R);
}
void build(int &root,int l,int r){
if(!root) root=++CNT;
if(l==r){
tree[root].val=WST::rt[l];
return;
}
build(tree[root].ls,l,mid);build(tree[root].rs,mid+1,r);//cout<<"root:"<<l<<' '<<r<<endl;
pushUp(root);
}
void getTheTrees(int root,int l,int r,int Ql,int Qr){
if(Ql<=l&&r<=Qr){
sta[++top]=tree[root].val;
return;
}
Qr<=mid?getTheTrees(tree[root].ls,l,mid,Ql,Qr):\
(Ql>=mid+1?getTheTrees(tree[root].rs,mid+1,r,Ql,Qr):\
(getTheTrees(tree[root].ls,l,mid,Ql,Qr),getTheTrees(tree[root].rs,mid+1,r,Ql,Qr)));
}
int query(int l,int r,int k){
if(l==r) return l;
int sum=0;
for(int i=1;i<=top;i++) sum+=WST::tree[WST::tree[sta[i]].ls].sum;
for(int i=1;i<=top;i++) sta[i]=k<=sum?WST::tree[sta[i]].ls:WST::tree[sta[i]].rs;
return k<=sum?query(l,mid,k):query(mid+1,r,k-sum);
}
#undef mid
void init(){
for(int i=1;i<=n;i++)
WST::update(WST::rt[i],_L,_R,arr[i],1);
build(rootOfSegtree,1,n);
}
int calc(int l,int r,int k){
top=0;
getTheTrees(rootOfSegtree,1,n,l,r);
return query(_L,_R,k);
}
#undef _L
#undef _R
int main(){
// freopen("in","r",stdin);
// freopen("out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;i++) arr[i]=read();
init();
int l,r,k;
for(int i=1;i<=m;i++){
l=read(),r=read(),k=read();
printf("%d\n",calc(l,r,k));
}
return 0;
}