二逼平衡树 Tyvj 1730 BZOJ3196 Loj#106

树状数组+主席树,模板题,不多说...

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <iostream>
#include <cstdlib>
using namespace std;
#define N 50005
#define lson l,m,tr[rt].ls
#define rson m+1,r,tr[rt].rs
#define PushUp(rt) tr[rt].siz=tr[tr[rt].ls].siz+tr[tr[rt].rs].siz
struct node
{
	int ls,rs,siz;
}tr[N*200];
int rot[N],a[N],n,Q,nx,ny,rx[N],ry[N],cnt;
void insert(int l,int r,int &rt,int v,int c)
{
	if(!rt)rt=++cnt;
	tr[rt].siz+=c;
	if(l==r)return ;
	int m=(l+r)>>1;
	if(m>=v)insert(lson,v,c);
	else insert(rson,v,c);
}
int query_k(int l,int r,int k)
{
	if(l==r)return l;
	int m=(l+r)>>1,sizls=0;
	for(int i=1;i<=nx;i++)sizls-=tr[tr[rx[i]].ls].siz;
	//printf("aaa%d %d %d %d\n",l,r,k,sizls);
	for(int i=1;i<=ny;i++)sizls+=tr[tr[ry[i]].ls].siz;
	//printf("bbb%d %d %d %d\n",l,r,k,sizls);
	if(sizls>=k)
	{
		for(int i=1;i<=nx;i++)rx[i]=tr[rx[i]].ls;
		for(int i=1;i<=ny;i++)ry[i]=tr[ry[i]].ls;
		return query_k(l,m,k);
	}
	for(int i=1;i<=nx;i++)rx[i]=tr[rx[i]].rs;
	for(int i=1;i<=ny;i++)ry[i]=tr[ry[i]].rs;
	return query_k(m+1,r,k-sizls);
}
int query_x(int l,int r,int x)
{
	if(l==r)return 1;
	int m=(l+r)>>1,sizls=0;
	for(int i=1;i<=nx;i++)sizls-=tr[tr[rx[i]].ls].siz;
	for(int i=1;i<=ny;i++)sizls+=tr[tr[ry[i]].ls].siz;
	if(m>=x)
	{
		for(int i=1;i<=nx;i++)rx[i]=tr[rx[i]].ls;
		for(int i=1;i<=ny;i++)ry[i]=tr[ry[i]].ls;
		return query_x(l,m,x);
	}
	for(int i=1;i<=nx;i++)rx[i]=tr[rx[i]].rs;
	for(int i=1;i<=ny;i++)ry[i]=tr[ry[i]].rs;
	return sizls+query_x(m+1,r,x);
}
void pre(int l,int r)
{
	nx=ny=0;
	for(int i=l;i;i-=(i&(-i)))rx[++nx]=rot[i];
	for(int i=r;i;i-=(i&(-i)))ry[++ny]=rot[i];
}
int main()
{
	scanf("%d%d",&n,&Q);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		for(int j=i;j<=n;j+=j&-j)
		{
			insert(-1<<30,1<<30,rot[j],a[i],1);
		}
	}
	while(Q--)
	{
		int op,x,y,z;
		scanf("%d%d%d",&op,&x,&y);
		if(op!=3)scanf("%d",&z),x--;
		if(op==1)
		{
			pre(x,y);
			printf("%d\n",query_x(-1<<30,1<<30,z));
		}else if(op==2)
		{
			pre(x,y);
			printf("%d\n",query_k(-1<<30,1<<30,z));
		}else if(op==3)
		{
			for(int i=x;i<=n;i+=i&-i)insert(-1<<30,1<<30,rot[i],a[x],-1);
			a[x]=y;
			for(int i=x;i<=n;i+=i&-i)insert(-1<<30,1<<30,rot[i],a[x],1);
		}else if(op==4)
		{
			pre(x,y);
			int rank=query_x(-1<<30,1<<30,z);
			pre(x,y);
			printf("%d\n",query_k(-1<<30,1<<30,rank-1));
		}else
		{
			pre(x,y);
			int rank=query_x(-1<<30,1<<30,z+1);
			pre(x,y);
			printf("%d\n",query_k(-1<<30,1<<30,rank));
		}
	}
	return 0;
}

  

posted @ 2018-05-04 11:23  Winniechen  阅读(262)  评论(0编辑  收藏  举报