[bzoj1500][NOI2005]维修数列[Treap][可持久化Treap]

非旋转式Treap1500 :)

  1 #include <bits/stdc++.h>
  2 #pragma    GCC    optimize(3)
  3 
  4 using namespace std;
  5 
  6 const int    INF=0x3f3f3f3f;
  7 
  8 struct node
  9 {
 10     int    val,key,size;
 11     int    sum,lx,rx,mx,revf,chgf;
 12     node    *l,*r;
 13     node() { }
 14     node(const int x)
 15     {
 16         mx=val=sum=x; key=rand();
 17         size=1; lx=rx=(x>0?x:0);
 18         chgf=INF; revf=0; l=r=0;
 19     }
 20 
 21     void    push_down()
 22     {
 23         if(chgf!=INF)
 24         {
 25             sum=chgf*size;
 26             val=chgf;
 27             lx=rx=(chgf>=0?sum:0);
 28             mx=(chgf>=0?sum:chgf);
 29             if(l) l->chgf=chgf;
 30             if(r) r->chgf=chgf;
 31             chgf=INF; revf=0;
 32         }
 33         if(revf)
 34         {
 35             if(l)l->revf^=1;
 36             if(r)r->revf^=1;
 37             swap(l,r);
 38             swap(lx,rx);
 39             revf=0;
 40         } return ;
 41     }
 42 
 43     void    update()
 44     {
 45         if(l)l->push_down();
 46         if(r)r->push_down();
 47         sum=(l?l->sum:0)+(r?r->sum:0)+val;
 48         size=(l?l->size:0)+(r?r->size:0)+1;
 49         mx=max(max((l?l->mx:-INF),(r?r->mx:-INF)),
 50           (l?l->rx:0)+(r?r->lx:0)+val);
 51         lx=max((l?l->lx:0), (l?l->sum:0)+val+(r?r->lx:0));
 52         rx=max((r?r->rx:0), (r?r->sum:0)+val+(l?l->rx:0));
 53         return ;
 54     }
 55 
 56 }U[510000],*Trash[510000],*ALL=U; int top;
 57 
 58 node *    ALLOC(const int x)
 59 {
 60     return new(top?Trash[top--]:++ALL)node(x);
 61 }
 62 
 63 void    RECYCLE(node * t)
 64 {
 65     if(!t)return ;
 66     RECYCLE(t->l);
 67     RECYCLE(t->r);
 68     Trash[++top]=t;
 69     return ;
 70 }
 71 
 72 struct Treap
 73 {
 74     typedef    pair<node *,node *> PNN;
 75     public:
 76     Treap() { root=0; }
 77 
 78     private:
 79 
 80     node * root;
 81 
 82     node *    merge(node * t1,node * t2)
 83     {
 84         if(!t1) return t2; if(!t2) return t1;
 85         t1->push_down(); t2->push_down();
 86         if(t1->key < t2->key)
 87             return t1->r=merge(t1->r,t2),t1->update(),t1;
 88         return t2->l=merge(t1,t2->l),t2->update(),t2;
 89     }
 90 
 91     PNN    split(node * t,const int pos)
 92     {
 93         if(t)  t->push_down();
 94         if(!t) return make_pair((node*)0,(node*)0);
 95         if(!pos) return make_pair((node*)0,t);
 96         if(t->l && t->l->size==pos)
 97         {
 98             node * temp=t->l;
 99             return t->l=0,t->update(),make_pair(temp,t);
100         }
101         if(t->l && t->l->size+1==pos)
102         {
103             node * temp=t->r;
104             return t->r=0,t->update(),make_pair(t,temp);
105         }
106         if(t->l && t->l->size>pos)
107         {
108             PNN    temp=split(t->l,pos);
109             return t->l=temp.second,t->update(),
110               make_pair(temp.first,t);
111         }
112         if(!t->r) return make_pair(t,(node*)0);
113         PNN    temp=split(t->r,pos-(t->l?t->l->size:0)-1);
114         return t->r=temp.first,t->update(),make_pair(t,temp.second);
115     }
116 
117     node *    build(const int * A,const int N)
118     {
119         stack<node *> stk; node * temp=0;
120         for(int i=0;i<N;++i)
121         {
122             node * t=ALLOC(A[i]);
123             while(!stk.empty() && t->key<stk.top()->key)
124                 temp=stk.top(),temp->update(),stk.pop();
125             if(!stk.empty())
126             {
127                 t->l=stk.top()->r;
128                 t->update();
129                 stk.top()->r=t;
130                 stk.top()->update();
131                 stk.push(t);
132             }
133             else
134             {
135                 t->l=temp;
136                 t->update();
137                 stk.push(t);
138             }
139         }
140         while(!stk.empty()) temp=stk.top(),temp->update(),stk.pop();
141         return temp;
142     }
143 
144     public:
145     void insert(const int pos,const int * A,const int N)
146     {
147         PNN    t=split(root,pos);
148         t.first=merge(t.first,build(A,N));
149         root=merge(t.first,t.second);
150         return ;
151     }
152 
153     void    erase(const int l,const int r)
154     {
155         PNN    t1=split(root,l-1);
156         PNN    t2=split(t1.second,r-l+1);
157         RECYCLE(t2.first);
158         root=merge(t1.first,t2.second);
159     }
160 
161     void    make_same(const int l,const int r,const int d)
162     {
163         PNN    t1=split(root,l-1);
164         PNN    t2=split(t1.second,r-l+1);
165         t2.first->chgf=d;
166         t2.first->push_down();
167         root=merge(t1.first,merge(t2.first,t2.second));
168     }
169 
170     void    reverse(const int l,const int r)
171     {
172         PNN    t1=split(root,l-1);
173         PNN    t2=split(t1.second,r-l+1);
174         t2.first->revf^=1;
175         t2.first->push_down();
176         root=merge(t1.first,merge(t2.first,t2.second));
177     }
178 
179     int    get_sum(const int l,const int r)
180     {
181         if(l>r)return 0;
182         PNN    t1=split(root,l-1);
183         PNN    t2=split(t1.second,r-l+1);
184         t2.first->push_down();
185         int    temp=t2.first->sum;
186         root=merge(t1.first,merge(t2.first,t2.second));
187         return temp;
188     }
189     
190     int    max_sum()
191     {
192         PNN    t1=split(root,0);
193         PNN    t2=split(t1.second,root->size);
194         t2.first->push_down();
195         int    temp=t2.first->mx;
196         root=merge(t1.first,merge(t2.first,t2.second));
197         return temp;
198     }
199 }S;
200 
201 int    n,m,x,y,z;
202 int    a[510000];
203 char    op[20];
204 
205 int main()
206 {
207     scanf("%d%d",&n,&m);
208     for(int i=0;i<n;++i) scanf("%d",&a[i]);
209     S.insert(0,a,n);
210     while(m--)
211     {
212         scanf("%s",op);
213         if(op[2]=='S') // Insert
214         {
215             scanf("%d%d",&x,&y);
216             for(int i=0;i<y;++i) scanf("%d",&a[i]);
217             S.insert(x,a,y);
218         }
219         if(op[2]=='L') // Delete
220         {
221             scanf("%d%d",&x,&y);
222             S.erase(x,x+y-1);
223         }
224         if(op[2]=='K') // Make_same
225         {
226             scanf("%d%d%d",&x,&y,&z);
227             S.make_same(x,x+y-1,z);
228         }
229         if(op[2]=='V') // Reverse
230         {
231             scanf("%d%d",&x,&y);
232             S.reverse(x,x+y-1);
233         }
234         if(op[2]=='T') // Get_sum
235         {
236             scanf("%d%d",&x,&y);
237             printf("%d\n",S.get_sum(x,x+y-1));
238         }
239         if(op[2]=='X') // Max_sum
240         {
241             printf("%d\n",S.max_sum());
242         }
243     }
244     
245     return 0;
246 }

 

posted @ 2017-01-21 14:07  Gster  阅读(240)  评论(0编辑  收藏  举报