【模板·主席树】 洛谷 P3834 【模板】可持久化线段树 1(主席树)

题目:主席树

思路:某位大佬的博客

代码:

using namespace std;

#define maxn (200000<<5)
#define read(x) scanf("%d",&x)
#define mid (L+R)/2

int n,T,m;

int c[maxn+5];	//离散化前 
int b[maxn+5],mp[maxn+5];	//离散化用 
int a[maxn+5];	//离散化后
int rt[maxn+5];	//第i个数对应的根节点 

struct Node{
	int x,lch,rch;
};

struct HJTbst{
	
	Node node[maxn+5];
	int P,cnt;
	
	void build(int& o,int L,int R) {
		o=++cnt;
		if(L==R) return ;
		build(node[o].lch,L,mid);
		build(node[o].rch,mid+1,R);
	}
	
	int update(int o,int L,int R) {
		cnt++;	//新建节点 
		node[cnt].lch=node[o].lch,node[cnt].rch=node[o].rch;
		node[cnt].x=node[o].x+1;
		if(L==R) return cnt;
		
		int och=cnt;
		if(P<=mid) node[och].lch=update(node[och].lch,L,mid);
		else node[och].rch=update(node[och].rch,mid+1,R);
		return och;
	}
	
	int query(int qL,int qR,int L,int R,int K) {
		int x=node[node[qR].lch].x-node[node[qL].lch].x;
		if(L==R) return L;
		if(x>=K) return query(node[qL].lch,node[qR].lch,L,mid,K);
		else return query(node[qL].rch,node[qR].rch,mid+1,R,K-x);
	}
	
} bst ;

int main() {
	read(n),read(T);
	for(int i=1;i<=n;i++) {
		read(c[i]),b[i]=c[i];
	}
	
	sort(b+1,b+n+1);	//离散化 
	m=unique(b+1,b+n+1)-b-1;
	for(int i=1;i<=m;i++) mp[b[i]]=i;
	for(int i=1;i<=n;i++) a[i]=mp[c[i]];
	
	bst.build(rt[0],1,m);	//建树 
	for(int i=1;i<=n;i++) {
		bst.P=a[i];
		rt[i]=bst.update(rt[i-1],1,m);
	}
	
	while(T--) {
		int x,y,z;
		read(x),read(y),read(z);
		printf("%d\n",b[bst.query(rt[x-1],rt[y],1,m,z)]);
	}
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值