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;
}
原文:http://www.cnblogs.com/heisenberg-/p/6547843.html