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

POJ 3468 A Simple Problem with Integers splay

时间:2014-11-07 08:38:43      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   color   ar   os   sp   for   

题意:给你一个数列,区间更新和区间询问

解题思路:splay指针版撸的,4700 ms险过

解题代码:

bubuko.com,布布扣
  1 // File Name: spoj3468.cpp
  2 // Author: darkdream
  3 // Created Time: 2014年11月05日 星期三 19时40分26秒
  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 #define LL long long
 25 #define maxn 100010
 26 using namespace std;
 27 int num[maxn];
 28 struct Splaynode{
 29      struct node{
 30         struct node *pre,*ch[2];
 31         LL add;
 32         LL sum; 
 33         LL val; 
 34         LL size;
 35      }*root;
 36      node *newnode(int c)
 37      {
 38         node * p = (node*)malloc(sizeof(node));
 39         p->pre = p->ch[0] = p->ch[1] = NULL;
 40         p->sum = p->val = c ;
 41         p->size = 1 ; 
 42         p->add = 0 ;
 43         return p ;
 44      }
 45      void push_down(node *x)
 46      {
 47         //printf("push_down***%lld\n",x->val);
 48         x->val += x->add;
 49         if(x->ch[0] != NULL)
 50         {
 51            x->ch[0]->sum += x->ch[0]->size * x->add;
 52            x->ch[0]->add += x->add;
 53         }
 54         if(x->ch[1] != NULL)
 55         {
 56            x->ch[1]->sum += x->ch[1]->size * x->add;
 57            x->ch[1]->add += x->add;
 58         }
 59         x->add = 0 ; 
 60      }
 61      void push_up(node *x)
 62      {
 63         x->size = 1;
 64         x->sum = x->val + x->add; 
 65         if(x->ch[0] != NULL)
 66         {
 67            x->size += x->ch[0]->size; 
 68            x->sum += x->ch[0]->sum;
 69         }
 70         if(x->ch[1] != NULL)
 71         {
 72            x->size += x->ch[1]->size;
 73            x->sum += x->ch[1]->sum;
 74         }
 75      }
 76      void print(node *x)
 77      {
 78          if(x == NULL)
 79              return;
 80          print(x->ch[0]);
 81          printf("%lld(%lld) ",x->val,x->sum);
 82          print(x->ch[1]);
 83          push_up(x);
 84      }
 85      void build(node *&x ,int l , int r ,node *f) //这里需要传递一个引用
 86      {
 87      //  printf("%d %d\n",l,r);
 88        if(l > r )
 89            return ; 
 90        int m = (l + r )  >> 1; 
 91        x = newnode(num[m]);
 92        build(x->ch[0],l,m-1,x);
 93        build(x->ch[1],m+1,r,x);
 94        x->pre = f ;
 95        push_up(x);
 96      }
 97      void init(int n)
 98      {
 99        root = NULL;
100        root = newnode(-1);
101        root->ch[1]=newnode(-1);
102        root->ch[1]->pre = root;
103        root->size = 2;
104        for(int i = 1;i <= n;i ++)
105          scanf("%d",&num[i]);
106        build(root->ch[1]->ch[0],1,n,root->ch[1]);
107        push_up(root->ch[1]);
108        push_up(root);
109      }
110      void Rotate(node *x ,int c)
111      {
112        node *y = x->pre;
113        //printf("%lld %lld\n",y->val,x->val);
114        push_down(y);
115        push_down(x);
116        y->ch[!c] = x->ch[c];
117        if(x->ch[c] != NULL)  x->ch[c]->pre = y; 
118        x->pre = y->pre;
119        if(y->pre != NULL)
120        {
121            if(y->pre->ch[0] == y) y->pre->ch[0] = x ;
122            else y->pre->ch[1] = x ; 
123        }
124        x->ch[c] = y,y->pre = x; 
125        push_up(y);
126      }
127      void Delete(node *x)
128      {
129          if(x == NULL)
130              return;
131          Delete(x->ch[0]);
132          Delete(x->ch[1]);
133          //printf("%lld\n",x->val);
134          free(x);
135          x = NULL;
136          if(x != NULL)
137              printf("****\n");
138          //x = NULL;
139          //printf("%lld\n",x->val);
140      }
141      void Splay(node *x ,node *f)
142      {
143        //printf("****\n");
144        push_down(x); //为何要push_down
145       // printf("****\n");
146        for(; x->pre != f ;)
147          if(x ->pre->pre == f)
148          { 
149              if(x->pre-> ch[0] == x)
150                 Rotate(x,1);
151              else Rotate(x,0);
152          }else{
153             node *y = x->pre ,*z = y ->pre;
154             if(z->ch[0] == y)
155             {
156                 if(y->ch[0] == x)
157                     Rotate(y,1),Rotate(x,1);
158                 else Rotate(x,0),Rotate(x,1);
159             }else{
160                 if(y->ch[1] == x)
161                     Rotate(y,0),Rotate(x,0);
162                 else
163                     Rotate(x,1),Rotate(x,0);
164             }
165          }
166        push_up(x);
167        if(f == NULL) root = x;
168      }
169      void Rotateto(int k ,node *goal)
170      {
171          node *x  = root;
172          push_down(x);
173          while(1)
174          {
175             if((x->ch[0] == NULL &&k == 0) || (x->ch[0]!= NULL && x->ch[0]->size == k))
176                 break;
177             if(x->ch[0] !=NULL && k < x->ch[0]->size)
178             {
179                 x = x->ch[0];
180             }else{
181                 k -= ((!x->ch[0])?1:x->ch[0]->size+1); 
182                 x = x->ch[1];
183             }
184             push_down(x);
185    //        printf("%lld %lld %d\n",x->val,x->size,k);
186          }
187         // printf("****\n");
188          //printf("%lld\n",x->pre->val);
189          Splay(x,goal);
190      }
191      void update()
192      {
193         int l , r, c; 
194         scanf("%d %d %d",&l,&r,&c);
195         Rotateto(l-1,NULL);
196         Rotateto(r+1,root);
197         root->ch[1]->ch[0]->add += c; 
198         root->ch[1]->ch[0]->sum += root->ch[1]->ch[0]->size * c; 
199      }
200      void query()
201      {
202        int l , r; 
203        scanf("%d %d",&l,&r);
204        Rotateto(l-1,NULL);
205     //   print(root);
206       // printf("\n");
207        Rotateto(r+1,root);
208       // print(root);
209       // printf("\n");
210       // printf("****\n");
211        printf("%lld\n",root->ch[1]->ch[0]->sum);
212      }
213 
214 }sp;
215 
216 int main(){
217     int n ,m;
218     scanf("%d %d",&n,&m);
219     sp.init(n);    
220     //sp.print(sp.root);;
221 //    printf("\n");
222     while(m--)
223     {
224        char op[10];
225        scanf("%s",op);
226        if(op[0] == Q)
227        {
228           sp.query();
229        }else {
230           sp.update();
231        }
232     }
233 //    while()
234     return 0;
235 }
View Code

 

POJ 3468 A Simple Problem with Integers splay

标签:style   blog   http   io   color   ar   os   sp   for   

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

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