noi 2005 维护数列 平衡树

非常恶心的一道数据结构题。

 

  1 #include<iostream>
  2 #include<cmath>
  3 #include<cstring>
  4 #include<cstdio>
  5 using namespace std;
  6 #define MAXN 510000
  7 #define INF 9876
  8 struct node
  9 {
 10     node *left,*right,*father;
 11     int value,size,sum,ml,mr,max;
 12     bool change,rev;
 13 };
 14 node *root,*nul;
 15 int top=0,n,m;
 16 int a[MAXN];
 17 void update(node *x)
 18 {
 19     if(x==nul)
 20         return ;
 21     x->size=x->left->size+x->right->size+1;
 22     x->sum=x->left->sum+x->right->sum+x->value;
 23     x->ml=max(x->left->ml,max(x->left->sum+x->value,x->left->sum+x->value+x->right->ml));
 24     x->mr=max(x->right->mr,max(x->right->sum+x->value,x->right->sum+x->value+x->left->mr));
 25     x->max=max(max(x->left->max,x->right->max),x->value);
 26     x->max=max(max(x->left->mr+x->value,x->right->ml+x->value),max(x->max,x->left->mr+x->right->ml+x->value));    
 27 }
 28 void push_down(node *x)
 29 {
 30     if(x==nul)
 31         return ;
 32     if(x->change)
 33     {
 34         x->change=0;
 35         x->right->change=x->left->change=1;
 36         x->left->value=x->right->value=x->value;
 37         if(x->left!=nul)
 38         {
 39             x->left->sum=x->left->max=x->left->ml=x->left->mr=x->value*x->left->size;
 40             if(x->value<0)
 41                 x->left->max=x->left->ml=x->left->mr=x->value;
 42         }
 43         if(x->right!=nul)
 44         {
 45             x->right->sum=x->right->max=x->right->ml=x->right->mr=x->value*x->right->size;
 46             if(x->value<0)
 47                 x->right->max=x->right->ml=x->right->mr=x->value;
 48         }
 49 
 50     }
 51     if(x->rev)
 52     {
 53         x->rev=0;
 54         swap(x->left,x->right);
 55         x->left->rev=!x->left->rev;
 56         x->right->rev=!x->right->rev;
 57         swap(x->left->ml,x->left->mr);
 58         swap(x->right->ml,x->right->mr);
 59     }
 60 }
 61 
 62 void dfs(node *t)
 63 {
 64     if(t->left!=nul)
 65         dfs(t->left);
 66     if(t->right!=nul)
 67         dfs(t->right);
 68     delete t;
 69 }
 70 void left_rotate(node *x)
 71 {
 72     node *y=x->father,*z=x->left;
 73     if(y==y->father->left) y->father->left=x;
 74     else y->father->right=x;
 75     x->father=y->father;
 76     x->left=y;
 77     y->father=x;
 78     y->right=z;
 79     z->father=y;
 80     update(y); update(x);
 81 }
 82 void right_rotate(node *x)
 83 {
 84     node *y=x->father,*z=x->right;
 85     if(y==y->father->right) y->father->right=x;
 86     else y->father->left=x;
 87     x->father=y->father;
 88     x->right=y;
 89     y->father=x;
 90     y->left=z;
 91     z->father=y;
 92     update(y); update(x);
 93 }
 94 void splay(node *rootnew,node *x)
 95 {
 96     push_down(x);
 97     node *fa=rootnew->father;
 98     while(x->father!=fa)
 99     {
100         node *y=x->father;
101         node *z=y->father;
102         if(z==fa)
103         {
104             if(x==y->left) 
105                 right_rotate(x);
106             else 
107                 left_rotate(x);
108             break;
109         }
110         if(y==z->left)
111             if(x==y->left) right_rotate(y),right_rotate(x);
112             else left_rotate(x),right_rotate(x);
113         else
114             if(x==y->left) right_rotate(x),left_rotate(x);
115             else left_rotate(y),left_rotate(x);
116     }
117     if(rootnew==root)
118         root=x;
119 }
120 void find(int pos,node *root)
121 {
122     node *x=root;
123     while(push_down(x),x->left->size+1!=pos)
124     {
125         if(x->left->size>=pos)
126             x=x->left;
127         else
128             pos-=x->left->size+1,x=x->right;
129     }
130     splay(root,x);
131 }
132 node* newnode(int value,node *f)
133 {
134     node *p=new node;
135     p->value=value;
136     p->size=1; p->father=f;
137     p->sum=p->max=p->ml=p->mr=value;
138     p->change=p->rev=0;
139     p->left=p->right=nul;
140     return p;
141 }
142 void insert(int pos,int tot,int a[])
143 {
144     node *p,*t;
145     p=t=newnode(a[1],nul);
146     for(int i=2;i<=tot;i++)
147         p=p->right=newnode(a[i],p);
148     find(pos+1,root);
149     find(1,root->right);
150     root->right->left=t;
151     t->father=root->right;
152     splay(root,p);
153 }
154 void del(int pos,int tot)
155 {
156     find(pos,root);
157     find(tot+1,root->right);
158     dfs(root->right->left);
159     root->right->left=nul;
160     update(root->right);
161     splay(root,root->right);
162 }
163 void change(int pos,int tot,int value)
164 {
165     find(pos,root);
166     find(tot+1,root->right);
167     root->right->left->change=1;
168     root->right->left->value=value;
169     node *p=root->right->left;
170     p->sum=p->max=p->ml=p->mr=p->value*p->size;
171     if(p->value<0)
172         p->max=p->ml=p->mr=p->value;
173     splay(root,root->right->left);
174 }
175 void reverse(int pos,int tot)
176 {
177     find(pos,root);
178     find(tot+1,root->right);
179     root->right->left->rev=!root->right->left->rev;
180     swap(root->right->left->ml,root->right->left->mr);
181     splay(root,root->right->left);
182 }
183 int get_sum(int pos,int tot)
184 {
185     find(pos,root);
186     find(tot+1,root->right);
187     return root->right->left->sum;
188 }
189 int max_sum()
190 {
191     return root->max;
192 }
193 
194 
195 void init()
196 {
197     nul=new node;
198     node *la=new node;
199     node *lb=new node;
200     nul->value=nul->ml=nul->mr=nul->max=-INF; nul->size=nul->sum=0;
201     la->value=la->ml=la->mr=la->max=-INF; la->size=2; la->sum=0;
202     lb->value=lb->ml=lb->mr=lb->max=-INF; lb->size=1; lb->sum=0;
203     root=la;
204     la->father=nul;
205     la->left=nul;
206     la->right=lb;
207     lb->father=la;
208     lb->left=lb->right=nul;
209 }
210 
211 char c[20];
212 int main()
213 {
214     int i,j,x,y,z,pos;
215     scanf("%d%d",&n,&m);
216     for(i=1;i<=n;i++)
217         scanf("%d",a+i);
218     init();
219     insert(0,n,a);
220     for(i=1;i<=m;i++)
221     {
222         scanf("%s",c);
223         switch(c[0])
224         {
225             case'I':
226                 scanf("%d%d",&pos,&n);
227                 for(j=1;j<=n;j++)
228                     scanf("%d",a+j);
229                 insert(pos,n,a);
230                 break;
231             case'D':
232                 scanf("%d%d",&pos,&n);
233                 del(pos,n);
234                 break;
235             case'R':
236                 scanf("%d%d",&pos,&n);
237                 reverse(pos,n);
238                 break;
239             case'G':
240                 scanf("%d%d",&pos,&n);
241                 printf("%d\n",get_sum(pos,n));
242                 break;
243             case'M':
244                 if(c[2]=='K')
245                 {
246                     scanf("%d%d%d",&pos,&n,&x);
247                     change(pos,n,x);
248                 }
249                 else
250                     printf("%d\n",max_sum());
251                 break;
252         }
253     }
254     return 0;
255 }

posted on 2012-07-23 20:52  myoi  阅读(646)  评论(0编辑  收藏  举报

导航