写的时候很纠结,磕磕绊绊的,断断续续的搞了好几天,其实前几天就写完了的,不过没a过题,正确性没经过历史的检验。今天无聊在杭电找了道Splay的入门题a了下,情况竟然出奇的顺利,除了因为内存泄露超内存了几次,改正后竟然一次AC了,RP啊,这次终于爆发了,从来都没这么顺利过= =!(PS:250+行的代码啊,以前100行不到的代码都能纠结很久的)
既然有Splay了,平衡树什么的也就懒的去搞了,,先将就着用了= =!(指针版的,数组版的内存维护太麻烦,指针版好写点)
//hdu1754 #include<iostream> using namespace std; #define MAXN 10000 struct EL //element { int v,size,vv,max;//key EL *l,*r,*father;//left son,right son bool operator <(EL const & rhs) const { if (v<rhs.v) return true; else if (v>rhs.v) return false; if (vv<rhs.vv) return true; else return false; } bool operator ==(EL const & rhs) const { if (v==rhs.v) return true; else return false; } }; struct Splay { EL *root; inline void update(EL* x) { x->size=1; x->max=x->vv; if (x->l!=NULL) x->size+=x->l->size; if (x->l!=NULL) if (x->l->max>x->max) x->max=x->l->max; if (x->r!=NULL) x->size+=x->r->size; if (x->r!=NULL) if (x->r->max>x->max) x->max=x->r->max; } inline LeftRotate(EL * x) { EL *y; y=x->father; if (x->l!=NULL) (x->l)->father=y; y->r=x->l; if (y!=NULL) { x->father=y->father; if (y->father!=NULL) if (y==y->father->l) y->father->l=x; else y->father->r=x; } x->l=y; y->father=x; update(x); update(y); } inline RightRotate(EL *x) { EL *y; y=x->father; if (x->r!=NULL) (x->r)->father=y; y->l=x->r; x->r=y; if (y!=NULL) { x->father=y->father; if (y->father!=NULL) if (y==y->father->l) y->father->l=x; else y->father->r=x; } y->father=x; update(x); update(y); } inline void Sp(EL *x,EL*y) //将x转到y下,y==NULL表示将x转到根 { while(x->father!=y) { if (x->father->father==y) //如果当前结点是目标节点的孩子的孩子,直接旋转一次即可,即当前节点直接变成目标节点的孩子 { if (x==x->father->l) RightRotate(x); else LeftRotate(x); } else if ( ((x->father->l==x)&&(x->father->father->l==x->father)) || ((x->father->r==x)&&(x->father->father->r==x->father)) )//如果当前结点,当前结点的父亲结点,当前结点的父亲结点的父亲结点三点成一直线,先旋转当前结点的父亲结点,再旋转当前结点。 { if (x->father->l==x) RightRotate(x->father),RightRotate(x); else LeftRotate(x->father),LeftRotate(x); } else //如果当前结点,当前结点的父亲结点,当前结点的父亲结点的父亲结点三点成一折线,先旋转当前结点,再旋转当前结点的父亲结点。 { if (x==x->father->l) RightRotate(x),LeftRotate(x); else LeftRotate(x),RightRotate(x); } } if (y==NULL) root=x; } inline void init() { root=NULL; } inline void add(EL vl) { EL *x,*prex; int flag; flag=0;prex=NULL; for(x=root;x!=NULL;) { x->size++; if (vl<(*x)) prex=x,flag=1,x=x->l; else prex=x,flag=2,x=x->r; } x=new EL; *x=vl; x->size=1; x->father=prex; if (flag==0) root=x; if (flag==1) prex->l=x; if (flag==2) prex->r=x; Sp(x,NULL); } inline EL * find(EL key) //找到返回地址,找不到的话返回NULL { EL *x=NULL; for(x=root;x!=NULL;) { if ((*x)==key) return x; else if ((*x)<key) x=x->r; else x=x->l; } return x; } inline int Rank(EL key) { EL * x=find(key); if (x==NULL) return -1; else { Sp(x,NULL); if (x->l!=NULL) return x->l->size+1; else return 1; } } inline EL * findRank_K(int k) //找第k大,找到的话返回地址,找不到返回NULL { EL *x; if (root==NULL) return NULL; for(x=root;x!=NULL;) { if (x->l!=NULL) { if (k==x->l->size+1) return Sp(x,NULL),x; else if (k<=x->l->size) x=x->l; else { k=k-(x->l->size+1); x=x->r; } } else { if (k==1) return Sp(x,NULL),x; k=k-1; x=x->r; } } if (x!=NULL) Sp(x,NULL); return x; } inline travel(EL *p) { if (p->l!=NULL) travel(p->l); cout<<p->v<<endl; if (p->r!=NULL) travel(p->r); } inline Delete(EL *x) { EL *y,*z; Sp(x,NULL); y=x->l; if (y!=NULL) while(y->r!=NULL) y=y->r; z=x->r; if (z!=NULL) while(z->l!=NULL) z=z->l; if ( (y==NULL)&&(z==NULL) ) root=NULL; if ( (y==NULL)&&(z!=NULL) ) {Sp(z,NULL);delete z->l;z->l=NULL;update(z);} if ( (y!=NULL)&&(z==NULL) ) {Sp(y,NULL);delete z->r;z->r=NULL;update(y);} if ( (y!=NULL)&&(z!=NULL) ) {Sp(y,NULL);Sp(z,y);delete z->l;z->l=NULL;update(z);update(y);} } }; Splay spt; int main() { int i,x,n,m,y,ans,pren; char c; char s[100]; EL temp,*t,*tt; temp.l=NULL; temp.r=NULL; temp.father=NULL; pren=0; while(scanf("%d %d",&n,&m)!=EOF) { if (pren!=0) { for(i=1;i<=pren;i++) { temp.v=i; spt.Delete(spt.find(temp)); } } pren=n; spt.init(); for(i=1;i<=n;i++) { scanf("%d",&temp.vv); temp.v=i; temp.max=temp.vv; spt.add(temp); } for(i=1;i<=m;i++) { gets(s); scanf("%c %d %d",&c,&x,&y); // spt.travel(spt.root); if (c=='U') { temp.v=x; t=spt.find(temp); t->vv=y; spt.Sp(t,NULL); } else { temp.v=x; t=spt.find(temp); temp.v=y; tt=spt.find(temp); spt.Sp(t,NULL); spt.Sp(tt,t); ans=t->vv; if (tt->vv>ans) ans=tt->vv; if (tt->l!=NULL) if (tt->l->max>ans) ans=tt->l->max; printf("%d/n",ans); } } } }