treap

P1801 黑匣子_NOI导刊2010提高(06)

然而并不知道treap有什么用

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstdlib>
using namespace std;
struct node
{
	node* ch[2];
	int r;
	int v;
	int s;
	node(int v) :v(v)
	{
		r=rand();
		ch[0]=ch[1]=NULL;
		s=1;
	}
	bool operator < (const node &b)const 
	{
		return r<b.r;
	}
	void sum()
	{
		s=1;
		if(ch[0]!=NULL)
			s+=ch[0]-> s;
		if(ch[1]!=NULL)
			s+=ch[1]-> s;
	}
	int cmp(int x) const
	{
		if(v==x)
			return -1;
		return x < v ? 0 : 1;
	}
};
void rotato(node* &x,int base)
{
	node *k=x->ch[base^1];
	x->ch[base^1]=k->ch[base];
	k->ch[base]=x;
	x->sum();
	k->sum();
	x=k;
	return ;
}
void insert(node* &x,int val)
{
	if(x==NULL)
		x=new node(val);
	else
	{
		int d=(val<x->v ? 0 : 1);
		insert(x->ch[d],val);
		if(x->ch[d]->r > x->r)
			rotato(x,d^1);
	}
	x->sum();
	//printf("%d ",x->s);
}
void remove(node* &x,int val)
{
	int d=x->cmp(val);
	if(d==-1)
	{
		node* u=x;
		if(x->ch[0]!=NULL&&x->ch[1]!=NULL)
		{
			int d1=(x->ch[0]->r > x->ch[1]-> r ? 1 : 0);
			rotato(x,d1);
			remove(x->ch[d1],val);
		}
		else
		if(x->ch[0]==NULL)
			x=x->ch[0];
		else
			x=x->ch[1];
		delete u;
	}
	else
		remove(x->ch[d],val);
	if(x!=NULL)
		x->sum();
}
int kth(node* x,int k)
{
	//printf("%d",x->s);
	if(x==NULL|| k <=0|| k > x->s )
		return 0;
	int s=(x->ch[0] == NULL ? 0 : x->ch[0]->s);
	if(k==s+1)
		return x->v;
	else
		if(k<=s)
			return kth(x->ch[0],k);
		else
			return kth(x->ch[1],k-s-1);
}
void merge(node* &src,node* &aim)
{
	if(src->ch[0]!=NULL)
		merge(src->ch[0],aim);
	if(src->ch[1]!=NULL)
		merge(src->ch[1],aim);
	insert(aim,src->v);
	delete src;
	src=NULL;
}
void removetree(node* &x)
{
	if(x->ch[0]!=NULL)
		removetree(x->ch[0]);
	if(x->ch[1]!=NULL)
		removetree(x->ch[1]);
	delete x;
	x=NULL;
}
int read()
{
	int s=0,f=1;
	char in=getchar();
	while(in<'0'||in>'9')
	{
		if(in=='-')
			f=-1;
		in=getchar();	
	}
	while(in>='0'&&in<='9')
	{
		s=(s<<1)+(s<<3)+in-'0';
		in=getchar();
	}
	return s*f;
}
node *root;
int add[200100],get[200100],num;
int main()
{
	int m=read(),n=read();
	num=1;
	root=NULL;
	for(int i=1;i<=m;i++)
		add[i]=read();
	for(int i=1;i<=n;i++)
		get[i]=read();
	for(int i=1;i<=m;i++)
	{
		insert(root,add[i]);
		//printf("%d",root->s);
		while(get[num]==i)
		{
			printf("%d\n",kth(root,num));
			num+=1;
		}
	}
	return 0;
}
posted @ 2018-04-19 21:27  Lance1ot  阅读(104)  评论(0编辑  收藏  举报