线段树套fhq线段树部分求调教
查看原帖
线段树套fhq线段树部分求调教
754502
_AyachiNene楼主2023/9/14 16:19
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[114514];
struct fhq
{
	struct node
	{
		int val,rnd,size;
		node *l,*r;
	};
	node *root=NULL;
	void update(node *p)
	{
		if(p==NULL)
			return;
		p->size=1;
		if(p->l!=NULL)
			p->size+=p->l->size;
		if(p->r!=NULL)
			p->size+=p->r->size;
	}
	node *New(int x)
	{
		node *p=new node;
		p->val=x;
		p->rnd=rand();
		p->size=1;
		p->l=p->r=NULL;
		return p;
	}
	node *merge(node *x,node *y)	
	{	
		if(x==NULL)
			return y;
		if(y==NULL)
			return x;
		if(x->rnd<=y->rnd)
		{
			x->r=merge(x->r,y);
			update(x);
			return x;
		}
		else
		{
			y->l=merge(x,y->l);
			update(y);
			return y;
		}
	}
	void split(node *p,int val,node *&x,node *&y)
	{
		if(p==NULL)
			x=y=NULL;
		else
		{
			if(p->val<=val)
			{
				x=p;
				split(p->r,val,p->r,y);
			}
			else
			{
				y=p;
				split(p->l,val,x,p->l);
			}
			update(p);
		}
	}
	void insert(int x)
	{
		node *a=NULL,*b=NULL;
		split(root,x,a,b);
		root=merge(merge(a,New(x)),b);
	}
	int Rank(int x)
	{
		node *a=NULL,*b=NULL;
		split(root,x-1,a,b);
		int ans=a?a->size+1:1;
		root=merge(a,b);	
		return ans;
	}
	int num(int x)
	{
		node *p=root;
		while(p!=NULL)
		{
			int ls=0;
			if(p->l) 
				ls=p->l->size;
			if(ls+1==x)
				break;
			else if(ls+1<x)
				x-=ls+1,p=p->r;
			else
				p=p->l;
		}
		return p->val;
	}
	void del(int x)
	{
		node *a=NULL,*b=NULL,*c=NULL;
		split(root,x,b,c);
		split(b,x-1,a,b);
		node *tmp1,*tmp2;
		if(!b) 
			tmp2=a;
		else
		{
			tmp1=merge(b->l,b->r),tmp2=merge(a,tmp1);
			if(b) 
				delete b;
		}
		root=merge(tmp2,c);
	}
	int pre(int x)
	{
		int ans;
		node *a=NULL,*b=NULL;
		split(root,x-1,a,b);
		node *p=a;
		if(a==NULL)
		{
			root=merge(a,b);
			return -INT_MAX;
		}
		while(p!=NULL)
			ans=p->val,p=p->r;
		root=merge(a,b);
		return ans;
	}
	int nxt(int x)	
	{
		int ans;
		node *a=NULL,*b=NULL;
		split(root,x,a,b);
		node *p=b;
		if(b==NULL)
		{
			root=merge(a,b);
			return INT_MAX;
		}
		while(p!=NULL)
			ans=p->val,p=p->l;
		root=merge(a,b);
		return ans;
	}
};
#define ls root*2
#define rs root*2+1
#define mid (t[root].l+t[root].r)/2
struct smt
{
	int l,r;
	fhq ft;
}t[114514*4];
void bld(int l,int r,int root)
{
	t[root].l=l;
	t[root].r=r;
	for(int i=l;i<=r;i++)
		t[root].ft.insert(a[i]);
	if(l==r)
		return;
	bld(l,mid,ls);
	bld(mid+1,r,rs);
}
int qrank(int x,int y,int root,int k)
{
	if(x<=t[root].l&&t[root].r<=y)
		return t[root].ft.Rank(k)-1;
	int res=0;
	if(x<=mid)
		res+=qrank(x,y,ls,k);
	if(y>mid)
		res+=qrank(x,y,rs,k);
	return res;
}
int qnum(int x,int y,int k)
{
	int l=0,r=1e8,ans=0;
	while(l<=r)
	{
		int Mid=(l+r)/2;
		if(qrank(x,y,1,Mid)<k)
			ans=Mid,l=Mid+1;
		else
			r=Mid-1;
	}
	return ans;
}
void add(int root,int k,int now)
{
	t[root].ft.del(a[k]);
	t[root].ft.insert(now);
	if(t[root].l==t[root].r)
		return;
	if(k<=mid)
		add(ls,k,now);
	else
		add(rs,k,now);
}
int qpre(int x,int y,int root,int k)
{
	if(t[root].l>=x&&t[root].r<=y)
		return t[root].ft.pre(k);
	int ans=-INT_MAX;
	if(x<=mid)
		ans=max(ans,qpre(x,y,ls,k));
	if(y>mid)
		ans=max(ans,qpre(x,y,rs,k));
	return ans;
}
int qnxt(int x,int y,int root,int k)
{
	if(x<=t[root].l&&t[root].r<=y)	
		return t[root].ft.nxt(k);
	int ans=INT_MAX;
	if(x<=mid)
		ans=min(ans,qnxt(x,y,ls,k));
	if(y>mid)
		ans=min(ans,qnxt(x,y,rs,k));
	return ans;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	bld(1,n,1);
	while(m--)
	{
		int op,l,r,k;
		cin>>op;
		if(op==1)
		{
			cin>>l>>r>>k;
			cout<<qrank(l,r,1,k)<<endl;
		}
		else if(op==2)
		{
			cin>>l>>r>>k;
			cout<<qnum(l,r,k)<<endl;
		}
		else if(op==3)
		{
			int p;
			cin>>p>>k;
			add(1,p,k);
		}
		else if(op==4)
		{
			cin>>l>>r>>k;
			cout<<qpre(l,r,1,k)<<endl;
		}
		else
		{
			cin>>l>>r>>k;
			cout<<qnxt(l,r,1,k)<<endl;
		}
	}
}
2023/9/14 16:19
加载中...