主席树

如果我们每添加一个元素都需要记住这个权值线段树的状态,以便于我们对历史的操作,那么如果只使用权值线段树,则我们需要n个权值线段树同时保存状态,对于非常多的元素,我们就需要保存非常多的权值线段树,这样做空间一定会爆炸,而主席树提供了这一功能。

板子

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
struct node
{
	int s,l,r;
}tr[N*20];
int root[N],idx;//root[x] 根节点的信息,idx 节点编号

//int &x 是传引用,给tr[x].l,tr[x].r赋值
void build(int &x,int l,int r)
{
	x=++idx;
	if(l==r)
		return ;
	int mid=(l+r)/2;
	build(tr[x].l,l,mid);
	build(tr[x].r,mid+1,r);
}

void insert(int x,int &y,int l,int r,int v)//x原先版本,y新版本
{
	y=++idx;
	tr[y]=tr[x];
	tr[y].s++;
	if(l==r)
		return ;
	int mid=(l+r)/2;
	if(v<=mid)
		insert(tr[x].l,tr[y].l,l,mid,v);
	else
		insert(tr[x].r,tr[y].r,mid+1,r,v);
}
/*
	for(int i=1;i<=n;i++)
		insert(root[i-1],root[i],1,n,a[i]);
*/


//查询[l,r]中第k小
long long query(int x,int y,int l,int r,int k)//x l-1版本,y r版本
{
	if(l==r)	return l;
	int mid=(l+r)/2;
	int s=tr[tr[x].l].s-tr[tr[y].l].s;
	if(k<=s)
		return query(tr[x].l,tr[y].l,l,mid,k);
	else
		return query(tr[x].r,tr[y].r,mid+1,l,k);		
}
/*
	cin>>l>>r>>k;
	query(l-1,r,1,n,k);
*/



//离散化 可见权值线段树



int main()
{

	return 0;
}
posted @ 2025-02-25 18:13  流氓兔LMT  阅读(13)  评论(0)    收藏  举报