码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-06-07 17:13:16      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

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选手谨慎使用双旋。

题解:注意内存的妥善利用。

  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;}

 

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

标签:

原文地址:http://www.cnblogs.com/chxer/p/4558658.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!