noi2004 郁闷的收纳员 treap

32 篇文章 0 订阅
5 篇文章 0 订阅

昨天有splay过了,今天上午上厕所的时候(= =)突然想到原来90分的程序有可能是因为cin的使用导致了超时。。。。然后中午回家一交果然100分了。。。

程序略长。。凑乎看吧。。那个优先队列的优化没用

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
 
using namespace std;
 
struct wbysr
{
	wbysr *l,*r;
	int size,dui,num;
	wbysr (int x)
	 {
	 	l=NULL;
	 	r=NULL;
	 	num=x;
	 	dui=rand()%100000+1;
	 }
}*root;
 
int n,i,m,ans=0,tot=0;
char c;
 
int size_l(wbysr *t)
{
	if(t->l)
	  return t->l->size;
	else
	 return 0;
}
 
int size_r(wbysr *t)
{
	if(t->r)
	  return t->r->size;
	else
	 return 0;
}
 
void rotate_left(wbysr *&t)//??,??????,??????  
{
	wbysr *p=t->r;
	t->r=p->l;
	p->l=t;
	p->size=t->size;
	t->size=size_l(t)+size_r(t)+1;
	t=p;
}
 
void rotate_right(wbysr *&t)
{
	wbysr *p=t->l;
	t->l = p->r;
    p->r = t;
    p->size = t->size;
    t->size=size_l(t)+size_r(t)+1;
    t=p;
}
 
int ask(wbysr *t,int d)
{
	if(t==root&&d>root->size)
	  return -1;
	int p=size_l(t);
	if(d==p+1)
	  return t->num;
	else
	if(d<=p)
	  return ask(t->l,d);
	else
	  return ask(t->r,d-1-p);
}
 
void insert(wbysr *&t,int d)
{
	if(!t)
	  {
	  	t=new wbysr(d);
	  	t->size=1;
	  }
	else
	if(d<=t->num)
	 {
	 	t->size++;
	 	insert(t->l,d);
	 	if(t->l->dui < t->dui)
	 	  rotate_right(t);
	 }
	else
	//if(d>t->num)
	  {
	  	t->size++;
	  	insert(t->r,d);	  	  
	  	if(t->r->dui < t->dui)
	  	  rotate_left(t);
	  }
}
 
void delete_(wbysr *&t,int d)
{
	if(t==NULL)
	  return;
	else
	if(d < t->num)
	{
		t->size--;
		delete_(t->l,d);
	}
	else
	if(d > t->num)
	{
		t->size--;
		delete_(t->r,d);
	} 
   else
   {
   	   if(t->l==NULL&&t->r==NULL)
   	     //delete t;
   	     t=NULL;
   	     //tf->l=NULL,tf->r=NULL;
   	   //t->num=0;
   	   else
   	   if(t->l==NULL)
   	     t=t->r;
   	   else
   	   if(t->r==NULL)
   	     t=t->l;
   	   else
   	    if(t->l->dui > t->r->dui)
   	     {
   	     	rotate_right(t);
   	     	t->size--;
   	     	delete_(t->r,d);
   	     }
   	    else
   	     {
   	     	rotate_left(t);
   	     	t->size--;
   	     	delete_(t->l,d);
   	     }
   }
}
 
void delete_2(wbysr *&t,int d)
{
	if(t==NULL)
	  return;
	else
	if(d < t->num)
	{
		t->size--;
		delete_(t->l,d);
	}
	else
   {
   	   if(t->l==NULL&&t->r==NULL)   	     
   	     t=NULL;   	  
   	   else
   	   if(t->l==NULL)
   	     t=t->r;   	   ;   	  
   	   /* else
   	     {
   	     	rotate_left(t);
   	     	t->size--;
   	     	delete_(t->l,d);
   	     }*/
   }
}
 
void find(wbysr *&t)
{
	if(t==NULL)
	  return;
	if(t->l==NULL)
	 {
	 	if(t->r==NULL)
	 	  t=NULL;
	 	else
	 	 {
	 	 	t=t->r;
	 	 }
	 }
	else
	 find(t->l);
}
 
int main()
{
	priority_queue<int,vector<int>,greater<int> > q;
	cin>>n>>m;
	int u=0;
	for(i=1;i<=n;i++)
	 {
	 	getchar();
	 	scanf("%c",&c);
	 	switch (c)
	 		{
	 		  case 'I':
	 		  	  {
	 		  	  	int y;
	 		  	  	scanf("%d",&y);
	 		  	  	if(y<m)
	 		  	  	   break;
	 		  	  	y-=u;
	 		  	  	insert(root,y);
	 		  	  	q.push(y);
	 		  	  	tot++;
	 		  	  	break;
	 		  	  }	 	
			  case 'A':
			     {
			     	int y;
			     	scanf("%d",&y);
			     	u+=y;
			     	//add(root,y);
			     	break;
			     }	  	 
			  case 'S':
			    {
			    	int y;
			    	scanf("%d",&y);
			    	u-=y;							
					//system("pause");
					int temp=q.top();	    				    	
					while(temp+u<m&&tot>1&&root!=NULL)
			    	 {			    	 	
			    	 	ans++;
			    	 	tot--;
			    	 	//find(root);
						 delete_2(root,temp);
						// find(root);
						 q.pop();
						 temp=q.top();	
						//cout<<ask(root,1)<<' '<<u<<' '<<tot<<endl;		    	 	
			    	 }
			    	 if(tot==1&&root->size==1&&root->num+u<m)
			    	  {		
					    q.pop();	    	 
			    	  	root=NULL;
			    	  	tot--;
			    	  	ans++;
			    	  	//cout<<tot<<endl;
			    	  }
			    	 /*for(int k=1;k<=2;k++)
			    	   cout<<ask(root,k)<<' '<<k<<' '<<root->size<<endl; 
			    	//delete_(root,6);
			    	for(int k=1;k<=2;k++)
			    	   cout<<ask(root,k)<<' '<<k<<' '<<root->size<<endl;//*/
			    	/*while(root!=NULL)
			    	  {
			    	  	cout<<ask(root,1)<<' '<<root->size<<endl;
			    	  	delete_(root,ask(root,1));			    	  	
			    	  }*/
			    	//add(root,-y);
			    	break;
			    }
			 case 'F':
			   {
			   	  int y;
			   	  scanf("%d",&y);
			   	  if(y>tot)
			   	    {
			   	    	printf("%d\n",-1);
						break;
			   	    }
			   	  printf("%d\n",u+ask(root,tot-y+1));
			   	  break;
			   }
	 		}
	 }
	printf("%d\n",ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值