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 ",tren[tren[klo].lson].hest-h); //splay(Root,tren[klo].lson);Root=tren[klo].lson; } } return 0; }