洛谷 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 }
时间: 2024-10-17 08:48:57

洛谷 P2042 维护数列的相关文章

动态规划 洛谷P2401 不等数列

P2401 不等数列 题目描述 将1到n任意排列,然后在排列的每两个数之间根据他们的大小关系插入">"和"<".问在所有排列中,有多少个排列恰好有k个"<".答案对2015取模. 注:1~n的排列指的是1~n这n个数各出现且仅出现一次的数列. 输入输出格式 输入格式: 第一行2个整数n,k. 输出格式: 一个整数表示答案. 输入输出样例 输入样例#1: 5 2 输出样例#1: 66 说明 对于30%的数据:n <= 10

洛谷 P2401 不等数列

其实有两种方法来解这道题 第一种:找规律(非正经) 一看,这玩意像是个杨辉三角,还左右对称呢 因为新插入一个数$n$,有$n+1$个位置可以选,所以总数就乘$n+1$,对应的$f[n+1][i]$也就等于$f[n][i]$了大概.可是一看,不大对,好像不是这样.那么就像,反正加一个数要么没变,要么加一个小于号,那么不在$f[n+1][i]$的一定是分到了$f[n+1][i+1]$里去了.那么以$n=3$时为例,$f[3][1]4=4,f[4][1]=1$也就是接收了$1$倍的$f[3][1]$.

斐波那契数列的通项公式x+洛谷P2626x

#include<cstdio> #include<iostream> #include<cmath> using namespace std; int main() { int n; scanf("%d",&n); n--; double q=sqrt(5.0); int ans; ans=((pow((1+q)/2.0,n)/q-(pow((1-q)/2.0,n)/n))); cout<<ans<<endl; re

洛谷P1182 数列分段Section II 二分答案

洛谷P1182 数列分段Section II 二分答案 题意:将 n 个 数 分为 m段 求一种方案,使这m段中最大的和 最小 额..可能有点拗口,其实就是说每一种方案,都有对应的 每段和的最大值,要求一种方案,使最大值最小 题解 :二分答案 mid为分成的最大值, 然后O(n) 判断 答案 是否可行 贪心的做下去,如果再加上就要超过了,那就新开一段 最后判断开的段数是否小于 m 1.注意要判断 如果当前这个值大于 mid,一个值就已经大于 mid了,那就直接退出了,否则 ,这个值也只会单独算为

洛谷1349 广义斐波那契数列 【矩阵乘法】

洛谷1349 广义斐波那契数列 题目描述 广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列.今给定数列的两系数p和q,以及数列的最前两项a1和a2,另给出两个整数n和m,试求数列的第n项an除以m的余数. 输入输出格式 输入格式: 输入包含一行6个整数.依次是p,q,a1,a2,n,m,其中在p,q,a1,a2整数范围内,n和m在长整数范围内. 输出格式: 输出包含一行一个整数,即an除以m的余数. 输入输出样例 输入样例#1: 1 1 1 1 10 7 输出样例#1: 6 说明

洛谷——P1062 数列

洛谷——P1062 数列 题目描述 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是: 1,3,4,9,10,12,13,… (该序列实际上就是:3^0,3^1,3^0+3^1,3^2,3^0+3^2,3^1+3^2,3^0+3^1+3^2,…) 请你求出这个序列的第N项的值(用10进制数表示). 例如,对于k=3,N=100,正确答案应该是981. 输入输出格式 输入格式: 输入文件只有1行,为2个正整数,用一个

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

题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值. 输入输出格式 输入格式: 第一行两个整数N和P(1≤P≤1000000000).第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N).第三行有一个整

洛谷 P2023 [AHOI2009]维护序列

P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值. 输入输出格式 输入格式: 第一行两个整数N和P(1≤P≤1000000000). 第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤100

洛谷P1471 方差

蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差. ——by 洛谷; http://www.luogu.org/problem/show?pid=1471 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<