2017.3.29 报表统计 思考记录

        有生之年第一道浙江省选题(虽然历史久远并且很水

     记录每个位置数列的左端点和右端点

        维护两颗splay   一颗维护全局最小差值,一颗维护相邻最小差值

          对于全局splay:每次插入时记录路径取差值min即可

            对于相邻最小差值splay:删除当前位置右端点和下一个位置左端点的差值,,再插入当前值和当前位置右端点差值   和    当前值和下一个位置左端点差值

            


            当我写完200行的程序调到崩溃 后看到了hzwer的程序只有80行时

           我是震惊的、、、  

                   

               看来stl是很好的东西。。

         

             惨不忍睹的代码:

#include<iostream>
#include<cstdio> 
using  namespace std;
#include<cmath>
int min1=1e9,min2=1e9,n,m,i,x,y,do12;
string str;
struct la
{
	int l,r;
}a[900000];
struct tree
{
	int zhi,cnt;
	tree *ch[2],*fu;
	int getwh()
	{
	return	fu->ch[0]==this?0:1;
	}
	void set(int wh,tree *child);
}p[5000000],*null,*root1,*root2;


void tree::set(int wh,tree *child)
{
	ch[wh]=child;
 if(child!=null)child->fu=this;
} 


int tot;
tree *xin(int k)
{
	tree *now=p+ ++tot;
	now->zhi=k;
	now->cnt=1;
	now->ch[0]=now->ch[1]=now->fu=null;
	return now;
}




inline void rotate(tree *&now)
{
tree *fu=now->fu;
tree *ye=now->fu->fu;
        int wh=now->getwh();
fu->set(wh,now->ch[wh^1]);
now->set(wh^1,fu);
 now->fu=ye;
 if(ye!=null)
 ye->ch[ye->ch[0]==fu?0:1]=now;
}
inline void splay(tree *now,tree *tar)
{
for(;now->fu!=tar;rotate(now))
        if(now->fu->fu!=tar)
now->getwh()==now->fu->getwh()?rotate(now->fu):rotate(now);
 
if(tar==null)
  do12==0?root1=now:root2=now;  
}
void ins(int k)
{//cout<<k;
	tree *now=do12==0?root1:root2,*last=null,*newone=xin(k);
	while(now!=null)
	{
		last=now;
	if(do12==0)min1=min(now->zhi-k>0?now->zhi-k:k-now->zhi,min1);
//	cout<<now->zhi<<"  ";
if(now->zhi==k)
{
	now->cnt++;
	splay(now,null);
	return;
}
	if(k>now->zhi)now=now->ch[1];
	else now=now->ch[0];
	}
	if(last==null)do12==0?root1=newone:root2=newone;
		
	if(last->zhi>k)last->set(0,newone);
    if(last->zhi<k)last->set(1,newone);
    
    
splay(newone,null); 
}






inline tree *find(int zhi)
{
tree *now=root2;
while(now!=null)
{  
  if(now->zhi==zhi)break;
 if(now->zhi>zhi)
  now=now->ch[0];
  else now=now->ch[1];
} 
if(now!=null)splay(now,null);
     return now;
}








void del(int value)
{
tree *now = find(value);
if (now == null) return;
if (now->cnt > 1)
{
now->cnt--;
return;
}




if (now->ch[0] == null && now->ch[1] == null)
root2 = null;
else if (now->ch[1] == null)
{
now->ch[0]->fu = null;
root2 = now->ch[0];
}
else if (now->ch[0] == null)
{
now->ch[1]->fu = null;
root2 = now->ch[1]; 
}
else
{
tree *_ = now->ch[0];
while (_->ch[1] != null) _ = _->ch[1];
splay(_, now);  
_->set(1, now->ch[1]);  
_->fu = null;
root2 = _;
}
}


int main()
{
//	freopen("form.in","r",stdin);
//	freopen("form.out","w",stdout);
	null=p;
	root1=root2=null;
	null->ch[0]=null->ch[1]=null->fu=null;
	null->zhi=0;	
	
	
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&x);
		do12=0;
		ins(x);
	//	cout<<x;


		a[i].r=a[i].l=x;
		if(i>1)
		{
				do12=1;
				ins(x-a[i-1].l>0?x-a[i-1].l:a[i-1].l-x);
				//cout<<a[i-1].l-x<<"oo  ";		
		}	
	}
		//cout<<root->ch[1]->zhi;
	for(i=1;i<=m;i++)
	{
		cin>>str;
	
		if(str=="INSERT")
		{
			scanf("%d%d",&x,&y);
               do12=0;
		   ins(y);
		  do12=1;
		   ins(a[x].r-y>0?a[x].r-y:y-a[x].r);
		    if(x<n)
  {
  	del(a[x].r-a[x+1].l>0?a[x].r-a[x+1].l:a[x+1].l-a[x].r);
  //	cout<<a[x].r-a[x+1].l<<" p ";
  	 ins(a[x+1].l-y>0?a[x+1].l-y:y-a[x+1].l);
  	
  }   a[x].r=y;
			
		}else if(str=="MIN_SORT_GAP")
		{
		    printf("%d\n",min1);		
		}else
		{ 
		   tree *now=root2,*last=null;
		 while(now!=null)last=now,now=now->ch[0];
		 printf("%d\n",last->zhi);		 	
		 }
	}
}


        


           

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值