COJ WZJ的数据结构(负十八)splay_tree的天堂

 

WZJ的数据结构(负十八)
难度级别:E; 运行时间限制:100000ms; 运行空间限制:700KB; 代码长度限制:2000000B
试题描述

对于前一段样例:

 

输入
输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目。 
第2行包含N个数字,描述初始时的数列。 
以下M行,每行一条命令,格式参见问题描述中的表格。为了考察垃圾回收的使用,我们精心准备了多组数据。。。
输出
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。 
输入示例
9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 0
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
3 3
1 2 3
MAKE-SAME 1 3 3
MAX-SUM
MAX-SUM
输出示例
-1
10
1
10
9
9
其他说明
样例见题目图片。
你可以认为在任何时刻,数列中至少有1个数。 
输入数据一定是正确的,即指定位置的数在数列中一定存在。  
50%的数据中,任何时刻数列中最多含有100个数; 100%的数据中,任何时刻数列中最多含有500个数。  
100%的数据中,任何时刻数列中任何一个数字均在[-1 000, 1 000]内。 
100%的数据中,M ≤20 000,插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
注意内存限制。请块状链表选手自重;由于数据不太好请Splay选手谨慎使用双旋。

更新:常数很小的一个版本,而且似乎要少coding一点。但是很容易写错?(雾

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cstring>
  7 #define PAU putchar(' ')
  8 #define ENT putchar('\n')
  9 #define CH for(int d=0;d<=1;d++) if(ch[d])
 10 using namespace std;
 11 const int maxn=500+10,inf=-1u>>1;inline int read();
 12 int max(int a,int b,int c){return max(max(a,b),c);}
 13 struct node{
 14     node*fa,*ch[2];
 15     int x,sm,mx,lx,rx,siz,set;bool rev;
 16     void init(){fa=ch[0]=ch[1]=NULL;x=sm=mx=lx=0;siz=1;set=inf;rev=false;return;}
 17     void revt(){
 18         swap(ch[0],ch[1]);swap(lx,rx);rev^=1;return;
 19     }
 20     void sett(int tag){
 21         set=x=tag;sm=tag*siz;mx=lx=rx=max(tag,tag*siz);return;
 22     }
 23     void down(){
 24         if(rev){CH{ch[d]->revt();}rev=false;}
 25         if(set!=inf){CH{ch[d]->sett(set);}set=inf;}
 26         return;
 27     }
 28     void update(){
 29         if(ch[0]&&ch[1]){
 30             siz=1+ch[0]->siz+ch[1]->siz;
 31             sm=x+ch[0]->sm+ch[1]->sm;
 32             lx=max(ch[0]->lx,ch[0]->sm+x+max(0,ch[1]->lx));
 33             rx=max(ch[1]->rx,ch[1]->sm+x+max(0,ch[0]->rx));
 34             mx=max(ch[0]->mx,ch[1]->mx,max(0,ch[0]->rx)+x+max(0,ch[1]->lx));
 35         }
 36         else if(ch[0]){
 37             siz=1+ch[0]->siz;
 38             sm=x+ch[0]->sm;
 39             lx=max(ch[0]->lx,ch[0]->sm+x);
 40             rx=x+max(0,ch[0]->rx);
 41             mx=max(ch[0]->mx,max(0,ch[0]->rx)+x);
 42         }
 43         else if(ch[1]){
 44             siz=1+ch[1]->siz;
 45             sm=x+ch[1]->sm;
 46             lx=x+max(0,ch[1]->lx);
 47             rx=max(ch[1]->rx,ch[1]->sm+x);
 48             mx=max(ch[1]->mx,x+max(0,ch[1]->lx));
 49         }
 50         else{
 51             siz=1;sm=x;lx=rx=mx=x;
 52         } return;
 53     }
 54 }Splay[maxn],*root,*nodecnt;
 55 queue<node*>RAM;
 56 void nodeinit(){
 57     nodecnt=Splay;return;
 58 }
 59 node*newnode(){
 60     node*t;if(!RAM.empty()) t=RAM.front(),RAM.pop();
 61     else t=nodecnt++;t->init();return t;
 62 }
 63 void del(node*&x){RAM.push(x);return;}
 64 void deltree(node*&x){if(!x)return;deltree(x->ch[0]);deltree(x->ch[1]);del(x);return;}
 65 int parent(node*x,node*&y){return (y=x->fa)?y->ch[0]==x?0:y->ch[1]==x?1:-1:-1;}
 66 void rotate(node*x){
 67     node*y,*z;int d1=parent(x,y),d2=parent(y,z);
 68     if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y;
 69     y->fa=x;x->fa=z;x->ch[d1^1]=y;
 70     if(d2!=-1) z->ch[d2]=x;
 71     y->update();return;
 72 }
 73 void pushdown(node*x){
 74     static node*s[maxn];int top=0;
 75     for(node*y;;x=y){
 76         s[top++]=x;y=x->fa;
 77         if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break;
 78     } while(top--) s[top]->down();return;
 79 }
 80 node*splay(node*x){
 81     pushdown(x);node*y,*z;int d1,d2;
 82     while(true){
 83         if((d1=parent(x,y))<0) break;
 84         if((d2=parent(y,z))<0){rotate(x);break;}
 85         if(d1==d2) rotate(y),rotate(x);
 86         else rotate(x),rotate(x);
 87     } x->update();return x;
 88 }
 89 node*find(node*x,int rank){
 90     x->down();int kth=x->ch[0]?x->ch[0]->siz+1:1;
 91     if(rank==kth) return x;
 92     if(rank<kth) return find(x->ch[0],rank);
 93     else return find(x->ch[1],rank-kth);
 94 }
 95 node*findlast(node*x){
 96     while(x->ch[1]) x->down(),x=x->ch[1];return x;
 97 }
 98 void split(node*&x,node*&y,int a){
 99     if(!a){y=x;x=NULL;return;}
100     x=splay(find(x,a));y=x->ch[1];x->ch[1]=NULL;
101     if(y)y->fa=NULL;x->update();return;
102 }
103 void split(node*&x,node*&y,node*&z,int a,int b){
104     split(x,z,b);split(x,y,a-1);return;
105 }
106 void join(node*&x,node*y){
107     if(!x){x=y;return;}if(!y)return;
108     x=splay(findlast(x));x->ch[1]=y;
109     if(y)y->fa=x;x->update();return;
110 }
111 void join(node*&x,node*y,node*z){
112     join(y,z);join(x,y);return;
113 }
114 int A[maxn];
115 void build(node*&x,int L,int R){
116     if(L>R)return;int M=L+R>>1;x=newnode();x->x=A[M];
117     build(x->ch[0],L,M-1);build(x->ch[1],M+1,R);
118     if(x->ch[0]) x->ch[0]->fa=x;
119     if(x->ch[1]) x->ch[1]->fa=x;
120     x->update();return;
121 }
122 void insert(int pos,int num){
123     for(int i=0;i<num;i++) A[i]=read();
124     node*x,*y;build(x,0,num-1);
125     split(root,y,pos);join(root,x,y);return;
126 }
127 void remove(int pos,int num){
128     node*x,*y;split(root,x,y,pos,pos+num-1);join(root,y);deltree(x);return;
129 }
130 void settag(int pos,int num,int tag){
131     node*x,*y;split(root,x,y,pos,pos+num-1);x->sett(tag);join(root,x,y);return;
132 }
133 void revtag(int pos,int num){
134     node*x,*y;split(root,x,y,pos,pos+num-1);x->revt();join(root,x,y);return;
135 }
136 int maxsum(int pos,int num){
137     if(!num)return 0;node*x,*y;split(root,x,y,pos,pos+num-1);int ans=x->sm;join(root,x,y);return ans;
138 }
139 int maxssm(){return root->mx;}
140 void printer(node*x){
141     if(!x) return;x->down();
142     printer(x->ch[0]);
143     printf("%d ",x->x);
144     printer(x->ch[1]);
145     return;
146 }
147 inline int read(){
148     int x=0,sig=1;char ch=getchar();
149     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
150     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
151     return x*=sig;
152 }
153 inline void write(int x){
154     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
155     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
156     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
157 }
158 void init(){
159     nodeinit();int n,m,pos,num;char s[15];
160     while(scanf("%d%d",&n,&m)==2){
161         for(int i=0;i<n;i++) A[i]=read();build(root,0,n-1);
162         while(m--){
163             scanf("%s",s);
164             if(s[0]=='M'&&s[2]=='X'){write(maxssm());ENT;continue;}
165             pos=read();num=read();
166             if(s[0]=='I') insert(pos,num);
167             else if(s[0]=='D') remove(pos,num);
168             else if(s[0]=='M') settag(pos,num,read());
169             else if(s[0]=='R') revtag(pos,num);
170             else write(maxsum(pos,num)),ENT;
171         } deltree(root);
172     }
173     return;
174 }
175 void work(){
176     return;
177 }
178 void print(){
179     return;
180 }
181 int main(){init();work();print();return 0;}

 

原来copy内存的不要命的做法。。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cstring>
  7 #define PAU putchar(' ')
  8 #define ENT putchar('\n')
  9 #define CH for(int d=0;d<=1;d++) if(ch[d])
 10 using namespace std;
 11 const int maxn=500+10,inf=-1u>>1;
 12 int max(int a,int b,int c){return max(a,max(b,c));}
 13 struct node{
 14     node*fa,*ch[2];
 15     int x;bool rev;int siz,sm,set,lx,rx,mx;
 16     node(){ch[0]=ch[1]=NULL;x=sm=0;lx=rx=mx=-inf;set=inf;rev=false;siz=1;}
 17     void init(){ch[0]=ch[1]=NULL;x=sm=0;lx=rx=mx=-inf;set=inf;rev=false;siz=1;return;}
 18     void revt(){swap(ch[0],ch[1]);swap(lx,rx);rev^=1;return;}
 19     void sett(int tag){x=set=tag;sm=tag*siz;lx=rx=mx=max(tag,tag*siz);return;}
 20     void update();
 21     void down(){
 22         if(rev){CH{ch[d]->revt();}rev=false;}
 23         if(set!=inf){CH{ch[d]->sett(set);}set=inf;}
 24         return;
 25     }
 26 }Splay[maxn],*root;int nodecnt=0;
 27 queue<node*>RAM;
 28 node*newnode(){
 29     node*t;if(!RAM.empty()) t=RAM.front(),RAM.pop();
 30     else t=&Splay[nodecnt++];t->init();return t;
 31 }
 32 void del(node*&x){RAM.push(x);return;}
 33 void deltree(node*&x){
 34     if(!x)return;deltree(x->ch[0]);deltree(x->ch[1]);del(x);return;
 35 }
 36 void copy(node*&x,node*y){
 37     x->x=y->x;
 38     x->lx=y->lx;
 39     x->mx=y->mx;
 40     x->rx=y->rx;
 41     x->sm=y->sm;
 42     x->siz=y->siz;
 43     x->set=y->set;
 44     x->rev=y->rev;
 45     return;
 46 }
 47 void node::update(){
 48     siz=1;sm=x;lx=mx=rx=0;node*n[2];n[0]=newnode();n[1]=newnode();
 49     CH{siz+=ch[d]->siz;sm+=ch[d]->sm;copy(n[d],ch[d]);}
 50     lx=max(n[0]->lx,n[0]->sm+x+max(0,n[1]->lx));
 51     rx=max(n[1]->rx,n[1]->sm+x+max(0,n[0]->rx));
 52     mx=max(0,n[0]->rx)+x+max(0,n[1]->lx);
 53     mx=max(n[0]->mx,n[1]->mx,mx);
 54     del(n[0]);del(n[1]);
 55     return;
 56 }
 57 int parent(node*x,node*&y){return (y=x->fa)?y->ch[1]==x?1:y->ch[0]==x?0:-1:-1;}
 58 void rotate(node*x){
 59     node*y,*z;int d1=parent(x,y),d2=parent(y,z);
 60     if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y;
 61     y->fa=x;x->fa=z;x->ch[d1^1]=y;
 62     if(d2!=-1) z->ch[d2]=x;
 63     y->update();return;
 64 }
 65 void pushdown(node*x){
 66     static node*s[maxn];int top=0;
 67     for(node*y;;x=y){
 68         s[top++]=x;y=x->fa;
 69         if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break;
 70     } while(top--) s[top]->down();return;
 71 }
 72 node*splay(node*x){
 73     pushdown(x);node*y,*z;int d1,d2;
 74     while(true){
 75         if((d1=parent(x,y))<0) break;
 76         if((d2=parent(y,z))<0){rotate(x);break;}
 77         if(d1==d2) rotate(y),rotate(x);
 78         else rotate(x),rotate(x);
 79     } x->update();return x;
 80 }
 81 node*find(node*x,int rank){
 82     x->down();int kth=1;if(x->ch[0]) kth=x->ch[0]->siz+1;
 83     if(rank==kth) return x;
 84     if(rank<kth) return find(x->ch[0],rank);
 85     else return find(x->ch[1],rank-kth);
 86 }
 87 void split(node*&x,node*&y,int a){
 88     if(!a){y=x;x=NULL;return;}
 89     x=splay(find(x,a));y=x->ch[1];
 90     x->ch[1]=NULL;if(y)y->fa=NULL;x->update();return;
 91 }
 92 void split(node*&x,node*&y,node*&z,int a,int b){
 93     split(x,z,b);split(x,y,a-1);return;
 94 }
 95 void join(node*&x,node*y){
 96     if(!x){x=y;return;}if(!y)return;
 97     x=splay(find(x,x->siz));x->ch[1]=y;
 98     if(y)y->fa=x;x->update();return;
 99 }
100 void join(node*&x,node*y,node*z){
101     join(y,z);join(x,y);return;
102 }
103 inline int read(){
104     int x=0,sig=1;char ch=getchar();
105     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
106     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
107     return x*sig;
108 }
109 inline void write(int x){
110     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
111     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
112     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
113 }
114 int s[maxn];
115 void build(node*&x,int L,int R){
116     if(L>R)return;int M=L+R>>1;
117     x=newnode();x->x=s[M];
118     build(x->ch[0],L,M-1);
119     build(x->ch[1],M+1,R);
120     if(x->ch[0]) x->ch[0]->fa=x;
121     if(x->ch[1]) x->ch[1]->fa=x;
122     x->update();return;
123 }
124 void insert(int pos,int num){
125     int ms=0;for(int i=0;i<num;i++) s[ms++]=read();
126     node*x,*y;build(x,0,num-1);
127     split(root,y,pos);join(root,x,y);return;
128 }
129 void remove(int L,int R){
130     node*x,*y;split(root,x,y,L,R);deltree(x);join(root,y);return;
131 }
132 void settag(int L,int R,int tag){
133     node*x,*y;split(root,x,y,L,R);x->sett(tag);join(root,x,y);return;
134 }
135 int getsum(int L,int R){
136     node*x,*y;split(root,x,y,L,R);int sm=x->sm;join(root,x,y);return sm;
137 }
138 int getssm(int L,int R){
139     node*x,*y;split(root,x,y,L,R);int mx=x->mx;join(root,x,y);return mx;
140 }
141 void reverse(int L,int R){
142     node*x,*y;split(root,x,y,L,R);x->revt();join(root,x,y);return;
143 }
144 void init(){
145     int n,Q;int pos,k,v;char str[15];
146     while(scanf("%d%d",&n,&Q)==2){
147         for(int i=0;i<n;i++) s[i]=read();build(root,0,n-1);
148         while(Q--){
149             scanf("%s",str);
150             if(str[0]=='I'){
151                 pos=read();k=read();
152                 insert(pos,k);
153             }
154             else if(str[0]=='D'){
155                 pos=read();k=read();
156                 remove(pos,pos+k-1);
157             }
158             else if(!strcmp(str,"MAKE-SAME")){
159                 pos=read();k=read();v=read();
160                 settag(pos,pos+k-1,v);
161             }
162             else if(!strcmp(str,"REVERSE")){
163                 pos=read();k=read();
164                 reverse(pos,pos+k-1);
165             }
166             else if(!strcmp(str,"GET-SUM")){
167                 pos=read();k=read();
168                 if(!k){puts("0");continue;}
169                 write(getsum(pos,pos+k-1));ENT;
170             }
171             else write(getssm(1,root->siz)),ENT;
172         } deltree(root);
173     }
174     return;
175 }
176 void work(){
177     return;
178 }
179 void print(){
180     return;
181 }
182 int main(){init();work();print();return 0;}

 

posted @ 2015-06-09 21:56  AI_Believer  阅读(243)  评论(0编辑  收藏  举报