[bzoj1500][NOI2005]维修数列[Splay]

1500 Splay版 自认为板子很美的我:)(捂脸)

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

 

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