主席树模板

int a[maxn];
vector<int>v;
	struct node{
		int ch[2];
		int s;
	}tr[maxn*22];
	int root[maxn],idx;
	void build(int &x,int l,int r){
		x=++idx;
		if(l==r)return;
		int m=l+r>>1;
		build(tr[x].ch[0],l,m);
		build(tr[x].ch[1],m+1,r);
	}
	void insert(int x,int &y,int l,int r,int v){//递归建立各个版本的线段树 
		//参数分别传:root[i-1],root[i],l,r,插入的值a[i] 
		y=++idx;
		tr[y]=tr[x];tr[y].s++;
		if(l==r)return;
		int m=l+r>>1;
		if(v<=m)insert(tr[x].ch[0],tr[y].ch[0],l,m,v);
		else insert(tr[x].ch[1],tr[y].ch[1],m+1,r,v);
	}
	int query(int x,int y,int l,int r,int k){
		//参数分别传root[l-1],root[r],1,n,k 
		if(l==r)return l;
		int m=l+r>>1;
		int s=tr[tr[y].ch[0]].s-tr[tr[x].ch[0]].s;
		if(k<=s)return query(tr[x].ch[0],tr[y].ch[0],l,m,k);
		else return query(tr[x].ch[1],tr[y].ch[1],m+1,r,k-s);
	}



int getid(int x){//返回x的下标 
	return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}

void solve(){
	int n,m;cin>>n>>m;
	
	for(int i=1;i<=n;i++){
		cin>>a[i];v.pb(a[i]);
	}
	
	sort(v.begin(),v.end());
	v.erase(unique(v.begin(),v.end()),v.end());

	int x=0;
	build(x,1,v.size());
	
	for(int i=1;i<=n;i++){
		insert(root[i-1],root[i],1,v.size(),getid(a[i]));
	}
	for(int i=1;i<=m;i++){
		int l,r,k;cin>>l>>r>>k;
		cout<<v[query(root[l-1],root[r],1,v.size(),k)-1]<<endl;
	}
}

posted @ 2025-03-13 20:36  Marinaco  阅读(13)  评论(0)    收藏  举报
//雪花飘落效果