洛谷 P2042 维护数列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P2042 维护数列相关的知识,希望对你有一定的参考价值。

http://blog.csdn.net/drazxlnddt/article/details/51051598

flip为true表示以当前节点为根的子树需要交换。set为true表示以当前节点为根的子树(包括自身)需要全部设为setv。

有个大坑:所谓和最大的子列最少有一个元素。有些操作可能对空的序列操作。

错误记录:所有注释掉的(多余的)和在之后加了//的语句(少的)

30和31行是为了更新子节点维护的各个值到正确的值(其他情况在split和merge中都是已经完成了更新,但如果字节点有setv的话没有)

注意53-55

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<ctime>
  4 using namespace std;
  5 template<typename T>
  6 class MyVec
  7 {
  8 private:
  9     static const int M_SIZE=500001;
 10     int rand1()
 11     {
 12         static int x=471;
 13         return x=(48271LL*x+1)%2147483647;
 14     }
 15 public:
 16     static const T zero=T();
 17     struct Node
 18     {
 19         Node(){}
 20         Node* ch[2];
 21         int r;
 22         bool flip,set;
 23         T v;
 24         T setv;
 25         int size;
 26         T sum;
 27         T max_sum[3];//0=>left,1=>right,2=>this
 28         void upd()
 29         {
 30             if(ch[0])   ch[0]->pushdown();//
 31             if(ch[1])   ch[1]->pushdown();//
 32             size=1+(ch[0]?ch[0]->size:0)+(ch[1]?ch[1]->size:0);
 33             sum=v+(ch[0]?ch[0]->sum:zero)+(ch[1]?ch[1]->sum:zero);
 34             max_sum[0]=max(ch[0]?ch[0]->max_sum[0]:zero,v+(ch[0]?ch[0]->sum:zero)+(ch[1]?ch[1]->max_sum[0]:zero));
 35             max_sum[1]=max(ch[1]?ch[1]->max_sum[1]:zero,v+(ch[1]?ch[1]->sum:zero)+(ch[0]?ch[0]->max_sum[1]:zero));
 36            // max_sum[2]=max(max(ch[0]?ch[0]->max_sum[2]:zero,ch[1]?ch[1]->max_sum[2]:zero),v+(ch[0]?ch[0]->max_sum[1]:zero)+(ch[1]?ch[1]->max_sum[0]:zero));
 37            max_sum[2]=v+(ch[0]?ch[0]->max_sum[1]:zero)+(ch[1]?ch[1]->max_sum[0]:zero);
 38            if(ch[0])    max_sum[2]=max(max_sum[2],ch[0]->max_sum[2]);
 39            if(ch[1])    max_sum[2]=max(max_sum[2],ch[1]->max_sum[2]);
 40         }
 41         void pushdown()
 42         {
 43             if(flip)
 44             {
 45                 swap(ch[0],ch[1]);
 46                 swap(max_sum[0],max_sum[1]);//
 47                 if(ch[0])    (ch[0]->flip)^=1;
 48                 if(ch[1])    (ch[1]->flip)^=1;
 49                 flip=0;
 50             }
 51             if(set)
 52             {
 53                 v=setv;//
 54                 sum=v*size;//
 55                 //max_sum[0]=max_sum[1]=max_sum[2]=v>0 ? v*size : 0;//
 56                 max_sum[0]=max_sum[1]=v>0 ? sum : 0;
 57                 max_sum[2]=v>0 ? sum : v;
 58                 if(ch[0])
 59                 {
 60                     //ch[0]->v=setv;
 61                     ch[0]->setv=setv;
 62                     ch[0]->set=1;
 63                 }
 64                 if(ch[1])
 65                 {
 66                     //ch[1]->v=setv;
 67                     ch[1]->setv=setv;
 68                     ch[1]->set=1;
 69                 }
 70                 set=0;
 71             }
 72         }
 73     }nodes[M_SIZE];
 74     Node* root;
 75     Node* que[M_SIZE];
 76     int que_top;
 77     Node* getnode()
 78     {
 79         return que[que_top--];
 80     }
 81     void delnode(Node* x)
 82     {
 83         que[++que_top]=x;
 84     }
 85     Node* merge(Node* a,Node* b)
 86     {
 87         if(a==NULL)    return b;
 88         if(b==NULL)    return a;
 89         if(a->r < b->r)
 90         {
 91             a->pushdown();a->ch[1]=merge(a->ch[1],b);a->upd();
 92             return a;
 93         }
 94         else
 95         {
 96             b->pushdown();b->ch[0]=merge(a,b->ch[0]);b->upd();
 97             return b;
 98         }
 99     }
100     //注意upd()
101     typedef pair<Node*,Node*> P;
102     P split(Node* a,int n)
103     {
104         if(a==NULL)    return P(NULL,NULL);
105         P y;
106         a->pushdown();int s=a->ch[0] ? a->ch[0]->size : 0;//
107         if(s>=n)
108         {
109             y=split(a->ch[0],n);
110             a->ch[0]=y.second;a->upd();
111             y.second=a;
112         }
113         else
114         {
115             y=split(a->ch[1],n-s-1);
116             a->ch[1]=y.first;a->upd();
117             y.first=a;
118         }
119         return y;
120     }
121     Node* kth(Node* o,int k)
122     {
123         if(o==NULL||k<=0||k > o->size)    return NULL;
124         P y=split(root,k-1);
125         P y2=split(y.second,1);
126         root=merge(merge(y.first,y2.first),y2.second);
127         return y2.first;
128     }
129     void erase(Node* &o,int k)
130     {
131         if(o==NULL||k<=0||k > o->size)    return;
132         P y=split(root,k-1);
133         P y2=split(y.second,1);
134         delnode(y2.first);
135         root=merge(y.first,y2.second);
136     }
137     void deltree(Node* o)
138     {
139         if(o->ch[0])    deltree(o->ch[0]);
140         if(o->ch[1])    deltree(o->ch[1]);
141         delnode(o);
142     }
143     T find_max_sum()
144     {
145         return root?root->max_sum[2]:zero;
146     }
147 public:
148     //在第k个之前插入
149     void insert(int k,const T& x)
150     {
151         Node* t=getnode();
152         t->ch[0]=t->ch[1]=NULL;t->r=rand1();t->v=x;t->flip=0;t->set=0;t->setv=zero;t->upd();
153         P y=split(root,k-1);
154         root=merge(merge(y.first,t),y.second);
155     }
156     void insert(int k,Node* x)
157     {
158         P y=split(root,k-1);
159         root=merge(merge(y.first,x),y.second);
160     }
161     MyVec()
162     {
163         que_top=M_SIZE-1;
164         for(int i=0;i<M_SIZE;i++)    que[i]=nodes+i;
165         root=NULL;
166     }
167     void push_back(const T& x)
168     {
169         insert(size()+1,x);
170     }
171     void pop_back()
172     {
173         erase(root,root->size);
174     }
175     void push_front(const T& x)
176     {
177         insert(1,x);
178     }
179     void pop_front()
180     {
181         erase(root,1);
182     }
183     Node* find_by_order(int k)
184     {
185         return kth(root,k);
186     }
187     T& operator[](int k)
188     {
189         return kth(root,k)->v;
190     }
191     void erase(int k)
192     {
193         erase(root,k);
194     }
195     //第k个开始删连续p个
196     void erase(int k,int p)
197     {
198         P y=split(root,k-1);
199         P y2=split(y.second,p);
200         root=merge(y.first,y2.second);
201         deltree(y2.first);
202     }
203     int size()
204     {
205         return root ? root->size : 0;
206     }
207     //翻转[l,r]
208     void reverse(int l,int r)
209     {
210         if(l>r) return;//
211         P y=split(root,l-1);
212         P y2=split(y.second,r-l+1);
213         //y2.first->pushdown();//
214         y2.first->flip^=1;
215         //y2.first->upd();
216         root=merge(merge(y.first,y2.first),y2.second);
217     }
218     Node* build(T *l,T *r)
219     {
220         if(l>r) return NULL;
221         if(l==r)
222         {
223             Node* t=getnode();
224             t->ch[0]=t->ch[1]=NULL;t->r=rand1();t->v=*l;t->flip=0;t->set=0;t->setv=zero;t->upd();
225             return t;
226         }
227         else
228         {
229             T* mid=l+(r-l)/2;
230             return merge(build(l,mid),build(mid+1,r));
231         }
232     }
233     T sum(int l,int r)
234     {
235         if(l>r) return zero;//
236         P y=split(root,l-1);
237         P y2=split(y.second,r-l+1);
238         //y2.first->upd();//
239         T ans=y2.first->sum;
240         root=merge(merge(y.first,y2.first),y2.second);
241         return ans;
242     }
243     void set(int l,int r,const T& x)
244     {
245         if(l>r) return;//
246         P y=split(root,l-1);
247         P y2=split(y.second,r-l+1);
248         //y2.first->pushdown();
249         y2.first->set=1;
250         y2.first->setv=x;
251         //y2.first->v=x;
252         //y2.first->upd();
253         root=merge(merge(y.first,y2.first),y2.second);
254     }
255 };
256 MyVec<int> x;
257 int n,m,l,r;
258 int a[4001000];
259 char ope[300];
260 int main()
261 {
262     //freopen("testdata.in","r",stdin);
263     //freopen("testdata.out","w",stdout);
264     int i,posi,tot,c;
265      MyVec<int>::Node* t;
266     scanf("%d%d",&n,&m);
267     for(i=1;i<=n;i++)
268         scanf("%d",&a[i]);
269     x.root=x.build(a+1,a+n);
270     while(m--)
271     {
272         scanf("%s",ope);
273         if(ope[2]==S)
274         {
275             scanf("%d%d",&posi,&tot);
276             for(i=1;i<=tot;i++) scanf("%d",&a[i]);
277             t=x.build(a+1,a+tot);
278             x.insert(posi+1,t);
279         }
280         else if(ope[2]==L)
281         {
282             scanf("%d%d",&posi,&tot);
283             x.erase(posi,tot);
284         }
285         else if(ope[2]==K)
286         {
287             scanf("%d%d%d",&posi,&tot,&c);
288             x.set(posi,posi+tot-1,c);
289         }
290         else if(ope[2]==V)
291         {
292             scanf("%d%d",&posi,&tot);
293             x.reverse(posi,posi+tot-1);
294         }
295         else if(ope[2]==T)
296         {
297             scanf("%d%d",&posi,&tot);
298             printf("%d\n",x.sum(posi,posi+tot-1));
299         }
300         else if(ope[2]==X)
301         {
302             printf("%d\n",x.find_max_sum());
303         }
304     //printf("%s %d %d %d\n",ope,posi,m,a[1]);
305       //for(i=1;i<=x.size();i++)    printf("%d ",x[i]);puts("");
306     }
307     return 0;
308 }

 

  1 #pragma GCC optimize(2)
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<ctime>
  5 using namespace std;
  6 template<typename T>
  7 class MyVec
  8 {
  9 private:
 10     static const int M_SIZE=500001;
 11     int rand1()
 12     {
 13         static int x=471;
 14         return x=(48271LL*x+1)%2147483647;
 15     }
 16 public:
 17     static const T zero=T();
 18     struct Node
 19     {
 20         Node(){}
 21         Node* ch[2];
 22         int r;
 23         bool flip,set;
 24         T v;
 25         T setv;
 26         int size;
 27         T sum;
 28         T max_sum[3];
 29         void upd()
 30         {
 31             if(ch[0])   ch[0]->pushdown();
 32             if(ch[1])   ch[1]->pushdown();
 33             size=1+(ch[0]?ch[0]->size:0)+(ch[1]?ch[1]->size:0);
 34             sum=v+(ch[0]?ch[0]->sum:zero)+(ch[1]?ch[1]->sum:zero);
 35             max_sum[0]=max(ch[0]?ch[0]->max_sum[0]:zero,v+(ch[0]?ch[0]->sum:zero)+(ch[1]?ch[1]->max_sum[0]:zero));
 36             max_sum[1]=max(ch[1]?ch[1]->max_sum[1]:zero,v+(ch[1]?ch[1]->sum:zero)+(ch[0]?ch[0]->max_sum[1]:zero));
 37            max_sum[2]=v+(ch[0]?ch[0]->max_sum[1]:zero)+(ch[1]?ch[1]->max_sum[0]:zero);
 38            if(ch[0])    max_sum[2]=max(max_sum[2],ch[0]->max_sum[2]);
 39            if(ch[1])    max_sum[2]=max(max_sum[2],ch[1]->max_sum[2]);
 40         }
 41         void pushdown()
 42         {
 43             if(flip)
 44             {
 45                 swap(ch[0],ch[1]);
 46                 swap(max_sum[0],max_sum[1]);
 47                 if(ch[0])    (ch[0]->flip)^=1;
 48                 if(ch[1])    (ch[1]->flip)^=1;
 49                 flip=0;
 50             }
 51             if(set)
 52             {
 53                 v=setv;
 54                 sum=v*size;
 55                 max_sum[0]=max_sum[1]=v>0 ? sum : 0;
 56                 max_sum[2]=v>0 ? sum : v;
 57                 if(ch[0])
 58                 {
 59                     ch[0]->setv=setv;
 60                     ch[0]->set=1;
 61                 }
 62                 if(ch[1])
 63                 {
 64                     ch[1]->setv=setv;
 65                     ch[1]->set=1;
 66                 }
 67                 set=0;
 68             }
 69         }
 70     }nodes[M_SIZE];
 71     Node* root;
 72     Node* que[M_SIZE];
 73     int que_top;
 74     Node* getnode()
 75     {
 76         return que[que_top--];
 77     }
 78     void delnode(Node* x)
 79     {
 80         que[++que_top]=x;
 81     }
 82     Node* merge(Node* a,Node* b)
 83     {
 84         if(a==NULL)    return b;
 85         if(b==NULL)    return a;
 86         if(a->r < b->r)
 87         {
 88             a->pushdown();a->ch[1]=merge(a->ch[1],b);a->upd();
 89             return a;
 90         }
 91         else
 92         {
 93             b->pushdown();b->ch[0]=merge(a,b->ch[0]);b->upd();
 94             return b;
 95         }
 96     }
 97     typedef pair<Node*,Node*> P;
 98     P split(Node* a,int n)
 99     {
100         if(a==NULL)    return P(NULL,NULL);
101         P y;
102         a->pushdown();int s=a->ch[0] ? a->ch[0]->size : 0;//
103         if(s>=n)
104         {
105             y=split(a->ch[0],n);
106             a->ch[0]=y.second;a->upd();
107             y.second=a;
108         }
109         else
110         {
111             y=split(a->ch[1],n-s-1);
112             a->ch[1]=y.first;a->upd();
113             y.first=a;
114         }
115         return y;
116     }
117     Node* kth(Node* o,int k)
118     {
119         if(o==NULL||k<=0||k > o->size)    return NULL;
120         P y=split(root,k-1);
121         P y2=split(y.second,1);
122         root=merge(merge(y.first,y2.first),y2.second);
123         return y2.first;
124     }
125     void erase(Node* &o,int k)
126     {
127         if(o==NULL||k<=0||k > o->size)    return;
128         P y=split(root,k-1);
129         P y2=split(y.second,1);
130         delnode(y2.first);
131         root=merge(y.first,y2.second);
132     }
133     void deltree(Node* o)
134     {
135         if(o->ch[0])    deltree(o->ch[0]);
136         if(o->ch[1])    deltree(o->ch[1]);
137         delnode(o);
138     }
139     T find_max_sum()
140     {
141         return root?root->max_sum[2]:zero;
142     }
143 public:
144     void insert(int k,const T& x)
145     {
146         Node* t=getnode();t->ch[0]=t->ch[1]=NULL;t->r=rand1();t->v=x;t->flip=0;t->set=0;t->setv=zero;t->upd();
147         P y=split(root,k-1);
148         root=merge(merge(y.first,t),y.second);
149     }
150     void insert(int k,Node* x)
151     {
152         P y=split(root,k-1);
153         root=merge(merge(y.first,x),y.second);
154     }
155     MyVec()
156     {
157         que_top=M_SIZE-1;
158         for(int i=0;i<M_SIZE;i++)    que[i]=nodes+i;
159         root=NULL;
160     }
161     void erase(int k,int p)
162     {
163         P y=split(root,k-1);
164         P y2=split(y.second,p);
165         root=merge(y.first,y2.second);
166         deltree(y2.first);
167     }
168     void reverse(int l,int r)
169     {
170         if(l>r) return;
171         P y=split(root,l-1);
172         P y2=split(y.second,r-l+1);
173         y2.first->flip^=1;
174         root=merge(merge(y.first,y2.first),y2.second);
175     }
176     Node* build(T *l,T *r)
177     {
178         if(l>r) return NULL;
179         if(l==r)
180         {
181             Node* t=getnode();t->ch[0]=t->ch[1]=NULL;t->r=rand1();t->v=*l;t->flip=0;t->set=0;t->setv=zero;t->upd();
182             return t;
183         }
184         else
185         {
186             T* mid=l+(r-l)/2;
187             return merge(build(l,mid),build(mid+1,r));
188         }
189     }
190     T sum(int l,int r)
191     {
192         if(l>r) return zero;
193         P y=split(root,l-1);
194         P y2=split(y.second,r-l+1);
195         T ans=y2.first->sum;
196         root=merge(merge(y.first,y2.first),y2.second);
197         return ans;
198     }
199     void set(int l,int r,const T& x)
200     {
201         if(l>r) return;
202         P y=split(root,l-1);
203         P y2=split(y.second,r-l+1);
204         y2.first->set=1;
205         y2.first->setv=x;
206         root=merge(merge(y.first,y2.first),y2.second);
207     }
208 };
209 MyVec<int> x;
210 int n,m,l,r;
211 int a[4001000];
212 char ope[300];
213 int main()
214 {
215     int i,posi,tot,c;
216     MyVec<int>::Node* t;
217     scanf("%d%d",&n,&m);
218     for(i=1;i<=n;i++)scanf("%d",&a[i]);
219     x.root=x.build(a+1,a+n);
220     while(m--)
221     {
222         scanf("%s",ope);
223         if(ope[2]==S) {scanf("%d%d",&posi,&tot);for(i=1;i<=tot;i++) scanf("%d",&a[i]);t=x.build(a+1,a+tot);x.insert(posi+1,t);}
224         else if(ope[2]==L){scanf("%d%d",&posi,&tot);x.erase(posi,tot);}
225         else if(ope[2]==K){scanf("%d%d%d",&posi,&tot,&c);x.set(posi,posi+tot-1,c);}
226         else if(ope[2]==V){scanf("%d%d",&posi,&tot);x.reverse(posi,posi+tot-1);}
227         else if(ope[2]==T){scanf("%d%d",&posi,&tot);printf("%d\n",x.sum(posi,posi+tot-1));}
228         else if(ope[2]==X){printf("%d\n",x.find_max_sum());}
229     }
230     return 0;
231 }

 

以上是关于洛谷 P2042 维护数列的主要内容,如果未能解决你的问题,请参考以下文章

[模板]洛谷T2042 NOI2005 维护数列 Splay

洛谷 P2023 [AHOI2009]维护序列

洛谷 P2023 BZOJ 1798 [AHOI2009]维护序列

luogu P2042

luogu P2042

洛谷 P1438 无聊的数列