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

HYSBZ 1500 [NOI2005]维修数列 splay

时间:2015-04-14 00:19:42      阅读:361      评论:0      收藏:0      [点我收藏+]

标签:

解题思路:终于把这道splay神题A掉了,splay专题也算是告一段落了,这个题主要的坑点,还是旋转和区间合并结合。

解题代码:

技术分享
  1 // File Name: hysbz1500.cpp
  2 // Author: darkdream
  3 // Created Time: 2015年04月10日 星期五 10时41分03秒
  4 
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 #include<climits>
 25 #define LL int
 26 #define INF INT_MAX
 27 #define maxn 500005
 28 using namespace std;
 29 
 30 struct SplayTree{
 31    int sz[maxn];
 32    int ch[maxn][2];
 33    int pre[maxn];
 34    int root , top1,top2;
 35    int ss[maxn],que[maxn];
 36    
 37    void Rotate(int x, int f){
 38         int y = pre[x];
 39         push_down(y);
 40         push_down(x);
 41         ch[y][!f] = ch[x][f];
 42         pre[ch[x][f]] = y ; 
 43         pre[x] = pre[y];
 44         if(pre[x]) ch[pre[y]][ch[pre[y]][1] == y] = x; 
 45         ch[x][f] = y;
 46         pre[y] = x; 
 47         push_up(y);
 48    }
 49    void Splay(int x, int goal){
 50         push_down(x);
 51         while(pre[x] != goal){
 52             if(pre[pre[x]] == goal){
 53                 Rotate(x,ch[pre[x]][0] == x);
 54             }else {
 55                 int y = pre[x],z = pre[y];
 56                 int f = (ch[z][0] == y);
 57                 if(ch[y][f] == x){
 58                     Rotate(x,!f),Rotate(x,f);
 59                 }else{
 60                     Rotate(y,f),Rotate(x,f);
 61                 }
 62             }
 63         }
 64         push_up(x);
 65         if(goal == 0) root = x; 
 66    }
 67    void RotateTo(int k ,int goal){
 68        int x = root;
 69        push_down(x);
 70        while(sz[ch[x][0]] != k ){
 71             if(k < sz[ch[x][0]]){
 72                 x = ch[x][0];
 73             }else {
 74                 k -= (sz[ch[x][0]] + 1);
 75                 x = ch[x][1];
 76             }
 77             push_down(x);
 78        }
 79        Splay(x,goal);
 80    }
 81    void erase(int x){
 82         int father = pre[x];
 83         int head = 0 , tail = 0 ; 
 84         for(que[tail ++] = x; head < tail ;head ++){
 85             ss[top2 ++] = que[head];
 86             if(ch[ que[head]][0]) que[tail ++] = ch[que[head]][0];
 87             if(ch[ que[head]][1]) que[tail ++] = ch[que[head]][1];
 88         }
 89         ch[father][ch[father][1] ==  x] = 0 ; 
 90         push_up(father);
 91    }
 92    void update_same(int x, int c)
 93    {
 94        if(x == 0 ) return ;
 95        cg[x] = c; 
 96        val[x] = c; 
 97        sum[x] = sz[x] * c; 
 98        lx[x] = rx[x] = mx[x] = max(c,c*sz[x]);
 99    }
100    void  update_rev(int x)
101    {
102        if(x == 0 )
103            return; 
104       rev[x] ^= 1; 
105       swap(lx[x],rx[x]);
106    }
107    void push_down(int x)
108    {
109        if(cg[x] != -INF)
110        {
111            update_same(ch[x][1],cg[x]);
112            update_same(ch[x][0],cg[x]);
113            rev[x] = 0 ; 
114            cg[x] = -INF; 
115        }else if(rev[x] == 1)
116        {
117             swap(ch[x][0],ch[x][1]);
118             update_rev(ch[x][0]);
119             update_rev(ch[x][1]);
120             rev[x] =  0 ; 
121        }
122    }
123    void push_up(int x){
124         sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]];
125         sum[x] =  val[x] + sum[ch[x][0]] + sum[ch[x][1]] ; 
126         lx[x] = rx[x] = sum[x];
127         mx[x] = sum[x];
128         if(ch[x][0] == 0  && ch[x][1] == 0 ){
129            return; 
130         }
131         if(ch[x][0] == 0 ){
132             lx[x] = max(val[x],lx[x]);
133             lx[x] = max(val[x]+lx[ch[x][1]],lx[x]);
134             rx[x] = max(rx[ch[x][1]],rx[x]);
135             mx[x] = max(mx[ch[x][1]],mx[x]);
136             mx[x] = max(lx[x],mx[x]);
137             mx[x] = max(rx[x],mx[x]);
138         }else if(ch[x][1] == 0 ){
139             lx[x] = max(lx[ch[x][0]],lx[x]);
140             rx[x] = max(val[x],rx[x]);
141             rx[x] = max(val[x] + rx[ch[x][0]],rx[x]);
142             mx[x] = max(mx[ch[x][0]],mx[x]);
143             mx[x] = max(lx[x],mx[x]);
144             mx[x] = max(rx[x],mx[x]);
145         }else{
146             lx[x] = max(lx[ch[x][0]],lx[x]);
147             lx[x] = max(sum[ch[x][0]] + val[x],lx[x]);
148             lx[x] = max(sum[ch[x][0]] + val[x] + lx[ch[x][1]],lx[x]);        
149             rx[x] = max(rx[ch[x][1]],rx[x]);
150             rx[x] = max(sum[ch[x][1]] + val[x],rx[x]);
151             rx[x] = max(sum[ch[x][1]] + val[x] + rx[ch[x][0]],rx[x]);
152             mx[x] = max(val[x],mx[x]);
153             mx[x] = max(mx[ch[x][0]],mx[x]);
154             mx[x] = max(mx[ch[x][1]],mx[x]);
155             mx[x] = max(rx[ch[x][0]]+val[x],mx[x]);
156             mx[x] = max(sum[ch[x][0]]+val[x],mx[x]);
157             mx[x] = max(lx[ch[x][1]]+val[x],mx[x]);
158             mx[x] = max(sum[ch[x][1]]+val[x],mx[x]);
159             mx[x] = max(lx[ch[x][1]]  + rx[ch[x][0]] + val[x],mx[x]);
160         }
161    }
162    void NewNode(int &x , LL c){
163         if(top2) x = ss[--top2];
164         else x = ++ top1;
165         rev[x] = ch[x][0] = ch[x][1] = pre[x] = 0 ;
166         sz[x] = 1; 
167         cg[x] = -INF;  
168         val[x] = sum[x] = lx[x] = rx[x] = mx[x] = c ; 
169    }
170    void build(int &x,int l ,int r ,int f){
171         if(l >  r) return ; 
172         int m = (l + r) >> 1; 
173         NewNode(x,num[m]);
174         build(ch[x][0],l,m-1,x);
175         build(ch[x][1],m+1,r,x);
176         pre[x] = f; 
177         push_up(x);
178    }
179    void init(){
180       rev[0] = ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0 ; 
181       lx[0] = rx[0] = mx[0] = sum[0] = 0;
182       cg[0] = -INF;
183       root = top1 = 0 ; 
184       NewNode(root,-1);
185       NewNode(ch[root][1],-1);
186       pre[ch[root][1]] = root;
187       sz[root] = 2; 
188       push_up(root);
189    }
190    void insert(int p ,int n){
191        for(int i =1 ;i <= n;i ++)
192             scanf("%d",&num[i]);
193        RotateTo(p,0);
194        RotateTo(p+1,root);
195        build(ch[ch[root][1]][0],1,n,ch[root][1]);
196        push_up(ch[root][1]);
197        push_up(root);
198    }
199    void Del(int p , int n){
200         RotateTo(p-1,0);
201         RotateTo(p+n,root);
202         erase(ch[ch[root][1]][0]);
203         push_up(ch[root][1]);
204         push_up(root);
205    }
206    void make(int p , int n, LL c){
207         RotateTo(p-1,0);
208         RotateTo(p+n,root);
209         update_same(ch[ch[root][1]][0],c);
210         push_up(ch[root][1]);
211         push_up(root);
212    }
213    void flip(int p ,int n ){
214        RotateTo(p-1,0);
215        RotateTo(p+n,root);
216        update_rev(ch[ch[root][1]][0]);
217    }
218    LL getsum(int p ,int n){
219         RotateTo(p-1,0);
220         RotateTo(p+n,root);
221         printf("%d\n",sum[ch[ch[root][1]][0]]);
222    }
223    LL maxsum(){
224         RotateTo(0,0);
225         RotateTo(sz[root]-1,root);
226         LL tmx = -INF;
227         tmx = max(lx[ch[ch[root][1]][0]],tmx);
228         tmx = max(rx[ch[ch[root][1]][0]],tmx);
229         tmx = max(mx[ch[ch[root][1]][0]],tmx);
230         printf("%d\n",tmx);
231    }
232    int rev[maxn];
233    LL val[maxn];
234    LL sum[maxn];
235    LL num[maxn];
236    LL mx[maxn];
237    LL rx[maxn];
238    LL lx[maxn];
239    LL cg[maxn];
240 }spt;
241 int n , m; 
242 char str[100];
243 int ta,tb;
244 LL tc;
245 int main(){
246   //freopen("in","r",stdin);
247   // freopen("output","w",stdout);
248     spt.init();
249     scanf("%d %d",&n,&m);
250     spt.insert(0,n);
251     while(m--){
252         scanf("%s",str);
253         if(str[0] == G){
254             scanf("%d %d",&ta,&tb);
255             spt.getsum(ta,tb);
256         }else if(str[0] == I){
257             scanf("%d %d",&ta,&tb);
258             spt.insert(ta,tb);
259         }else if(str[0] == D){
260             scanf("%d %d",&ta,&tb);
261             spt.Del(ta,tb);
262         }else if(str[0] == M && str[2] == K){
263             scanf("%d %d %d",&ta,&tb,&tc);
264             spt.make(ta,tb,tc);
265         }else if(str[0] == R){
266             scanf("%d %d",&ta,&tb);
267             spt.flip(ta,tb);
268         }else {
269         //    spt.debug(spt.root);
270             spt.maxsum();
271         /*spt.debug(spt.root);
272         printf("\n");
273         spt.print(spt.root);
274         printf("\n");
275             spt.maxsum();*/
276         }
277     }
278 return 0;
279 }
View Code

 

HYSBZ 1500 [NOI2005]维修数列 splay

标签:

原文地址:http://www.cnblogs.com/zyue/p/4423582.html

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