SPOJ - QMAX3VN (4350) splay


SPOJ - QMAX3VN一个动态的序列 ,在线询问某个区间的最大值。关于静态序列的区间最值问题,用ST表解决,参考POJ 3264

乍一看上去 splay可以轻松解决。书上说可以用块状链表解决,也没说具体怎么做。我也想不出来。

直接给splay代码吧,比较裸,这道题常数卡的有点紧,要注意优化。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=400000,h=1e+9;

int Root,n,m;
struct Node
{
 int val,cnt,size;
 bool rev;
 int father;int lson;int rson; int hei;int hest;
 Node(int v,int height,int c,int fa,int l,int r)
 	{this->val=v;this->hei=height;this->hest=height;this->cnt=c;this->father=fa;this->lson=l;this->rson=r;rev=false;} 
}tren[maxn]=Node(0,0,0,0,0,0);


queue<int> memq;

int newnode()
{
 int loc=memq.front();memq.pop();
 return loc;
}

void dele(int loc)
{
 memq.push(loc);
 return ;
}

void pushdown(int x)
{
 if(x==0)return ;
 if(tren[x].rev)
 	{
 	 tren[x].rev=false;
	 swap(tren[x].lson,tren[x].rson);
	 if(tren[x].lson!=0)tren[tren[x].lson].rev=!tren[tren[x].lson].rev;
	 if(tren[x].rson!=0)tren[tren[x].rson].rev=!tren[tren[x].rson].rev;	
	}
}

void update(int x)
{
 tren[x].size=tren[x].cnt;
 tren[x].hest=tren[x].hei;
 if(tren[x].lson!=0){tren[x].size+=tren[tren[x].lson].size;tren[x].hest=max(tren[x].hest,tren[tren[x].lson].hest);}
 if(tren[x].rson!=0){tren[x].size+=tren[tren[x].rson].size;tren[x].hest=max(tren[x].hest,tren[tren[x].rson].hest);}
}

void zig(int x)
{
 int fa=tren[x].father;
 pushdown(fa);pushdown(x);
 if(tren[tren[fa].father].lson==fa){tren[tren[fa].father].lson=x;}
 	else  {tren[tren[fa].father].rson=x;}
 tren[x].father=tren[fa].father;
 tren[fa].father=x;
 tren[fa].lson=tren[x].rson;
 tren[tren[x].rson].father=fa;
 tren[x].rson=fa;
 update(tren[x].rson);update(x);//update(tren[x].father);
 //swap(tren[fa],tren[x]);
}


void zag(int x)
{
 int fa=tren[x].father;
 pushdown(fa);pushdown(x);
 if(tren[tren[fa].father].lson==fa){tren[tren[fa].father].lson=x;}
 	else  {tren[tren[fa].father].rson=x;}
 tren[x].father=tren[fa].father;
 tren[fa].father=x;
 tren[fa].rson=tren[x].lson;
  tren[tren[x].lson].father=fa;
 tren[x].lson=fa;
 update(tren[x].lson);update(x);//update(tren[x].father);
  //swap(tren[fa],tren[x]);
}

void splay(int  root,int now)//核心 
{
 if(root==0||now==0)return ;
 int end=tren[root].father;
 while(tren[now].father!=end)
 	{
 	 if(tren[now].father==root)
 	 	{
 	 	 if(tren[tren[now].father].lson==now)zig(now);
 	 	 	else zag(now);
 	 	 return ;
		}
	 int fa=tren[now].father;int grand=tren[fa].father;
	 if(tren[grand].lson==fa)
	 	{
	 	 if(tren[fa].lson==now){zig(fa);zig(now);continue;}
	 	 	else{zag(now);zig(now);continue;}
		}
	  else{
	  	   if(tren[fa].rson==now){zag(fa);zag(now);continue;}
	  	   if(tren[fa].lson==now){zig(now);zag(now);continue;}
	  	  }
	}
 return ;
}

int insert(int fa,int root,int value)
{
 int ans;
 pushdown(root);
 if(root==0)
 	{
 	 root=newnode();
 	 tren[root]=Node(value,0,1,fa,0,0);
 	 update(root);
 	 ans= root;
 	 //splay(1,root);
	}
 if(tren[root].val==value)
 	{tren[root].cnt++;update(root);ans=0;}
 if(tren[root].val>value)
 	{
 	 if(tren[root].lson==0)
 	 	{
 	 	 tren[root].lson=newnode();
 	 	 tren[tren[root].lson]=Node(value,0,1,root,0,0);
 	 	 update(tren[root].lson);
 	 // splay(1,tren[root].lson);
 	 	 ans=  tren[root].lson;	
		}
	 else ans= insert(root,tren[root].lson,value);
	}
 	else 
 		{
 		 if(tren[root].rson==0)
 	 		{
 	 	 		tren[root].rson=newnode();
 	 	 		tren[tren[root].rson]=Node(value,0,1,root,0,0);
 	 	 		update(tren[root].rson);
 	 	 		//splay(1,tren[root].rson);
 	 	 		ans= tren[root].rson;	
			}
				else ans= insert(root,tren[root].rson,value);
		}
 update(root);
 return ans;
}

int access(int root,int key)
{
 pushdown(root);
 if(tren[root].val==key)return root;
 if(tren[root].val<key)return access(tren[root].rson,key);
 	else return access(tren[root].lson,key);
}

int Max(int root)
{
 pushdown(root);
 if(root==0||tren[root].rson==0)return root;
 	else return Max(tren[root].rson);
}

int join(int l,int r)
{
 if(l==0)return r;
 if(r==0)return l;
 int max=Max(l);
 splay(l,max);
 tren[max].rson=r;
 return max;
}

void erase(int root,int key)
{
 int now=access(root,key);
 int fa=tren[now].father;
 if(tren[now].cnt>1){tren[now].cnt--;return ;}
 	else
	 {
 	  if(tren[fa].lson==now){tren[fa].lson=join(tren[now].lson,tren[now].rson);}	
 	  	else{tren[fa].rson=join(tren[now].lson,tren[now].rson);}
	 }
 return ;
}

int getKth(int root,int k)
{
 while(root!=0&&k<=tren[root].size)
 	{
 	 pushdown(root);
 	 int ls=tren[root].lson,rs=tren[root].rson;
 	 if(ls!=0&&k<=tren[ls].size){root=ls;continue;}
 	 k-=tren[root].cnt;
 	 if(ls!=0)k-=tren[ls].size;
 	 if(k<=0){return root;}
 	 root=rs;
	}
}

void maintain(int now,int val)
{
 while(now!=0)
 	{
	  tren[now].size+=val;
	  now=tren[now].father;
	}
}
vector<int>ans;
void print( int  root)
{
 if(root==0)return ;
 pushdown(root);
 print(tren[root].lson);
 if(tren[root].val<=n&&tren[root].val>=1)ans.push_back(tren[root].val);
 print(tren[root].rson);
}

int main()
{freopen("t.txt","r",stdin);
 //freopen("1.txt","w",stdout);
 scanf("%d",&n);
 int tot=3;
 tren[1]=Node(0,-1,1,0,0,0);
 Root=1;
 tren[2]=Node(0,-1,1,0,0,0);
 tren[1].rson=2;
 tren[2].father=1;
 update(2);update(1);
 
 int k=0;
 for(int i=0;i<n;i++)
 	{
 	 char c;int a,b,l,r;
	 scanf("%s%d%d",&c,&a,&b);
	 if(c=='A')
	 	{
	 	 a+=h;
	 	 l=b;
	 	 r=b+1;
	 	 int klo=getKth(Root,l);
	 	 int klb,newson;
	 	 if(tren[klo].rson!=0)
	 	 {
		  
	 	  klb=getKth(tren[klo].rson,1);
	 	  newson=tren[klb].lson=tot++;
	 	  
	 	}else{ klb=klo; newson=tren[klb].rson=tot++;}
	 	 tren[newson]=Node(1,a,1,klb,0,0);
	 	 klo=newson;
	 	 while(klo!=0)
	 	 	{
	 	 	 update(klo);
	 	 	 klo=tren[klo].father;
			}
		 
		 splay(Root,newson);Root=newson;
		} 
	 if(c=='Q')
	 	{
	 	 l=a;
	 	 r=b+2;
	 	 int klo=getKth(Root,l);
	 	 splay(Root,klo);Root=klo;
	 	 klo=getKth(Root,r);
	 	 splay(tren[Root].rson,klo);
	 	 printf("%d\n",tren[tren[klo].lson].hest-h);
	 	 //splay(Root,tren[klo].lson);Root=tren[klo].lson;
		}
	}
 
 
 
 return 0;
}

  

优质内容筛选与推荐>>
1、线程、线程池
2、数据库置疑问题解决
3、关于git的简单实用命令
4、数据高可用
5、表格


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号