[NOI2005] 维护数列

[NOI2005] 维护数列

题目

传送门

请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格)

操作编号

输入文件中的格式

说明

1.  插入

INSERT_posi_tot_c1_c2_..._ctot

在当前数列的第 posi 个数字后插入 tot

个数字:c1, c2, …, ctot;若在数列首插

入,则 posi 为 0

2.  删除

DELETE_posi_tot

从当前数列的第 posi 个数字开始连续

删除 tot 个数字

3.  修改

MAKE-SAME_posi_tot_c

将当前数列的第 posi 个数字开始的连

续 tot 个数字统一修改为 c

4.  翻转

REVERSE_posi_tot

取出从当前数列的第 posi 个数字开始

的 tot 个数字,翻转后放入原来的位置

5.  求和

GET-SUM_posi_tot

计算从当前数列开始的第 posi 个数字

开始的 tot 个数字的和并输出

6.  求和最

大的子列

MAX-SUM

求出当前数列中和最大的一段子列,

并输出最大和

INPUT

输入文件的第 1 行包含两个数 N 和 M,N 表示初始时数列中数的个数,M表示要进行的操作数目。

第 2 行包含 N 个数字,描述初始时的数列。

以下 M 行,每行一条命令,格式参见问题描述中的表格。

OUTPUT

对于输入数据中的 GET-SUM 和 MAX-SUM 操作,向输出文件依次打印结果,每个答案(数字)占一行。

SAMPLE

INPUT

9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM

OUTPUT

-1

10

1

10

解题报告

做这道题前请做好心理准备= =

比如说你会看到这样的评论:

QhelDIV:记得byvoid的博客上说这个题他当时写了整整一天,
我大约写了8个小时?
这种长代码程序结构一定要简单简单再简单,否则就是无限的调试了

Chenyao2333:策爷:“splay/块状链表的自虐题。”。深刻理解到如果没有M倾向就不要去写这题了。。。

wumingshi:这道题太恶心辣
一定要处理好哨兵节点和null节点的数据,update时要注意!
【没有用哨兵节点的请随意

很裸的SpalySplay板子题,然而并不是那么好打= =

本来打了256行的数组板子

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 using namespace std;
  5 inline int read(){
  6     int sum(0),f(1);
  7     char ch(getchar());
  8     for(;ch<'0'||ch>'9';ch=getchar())
  9         if(ch=='-')
 10             f=-1;
 11     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
 12     return sum*f;
 13 }
 14 int ch[4000001][2],f[4000001],key[4000001],size[4000001];
 15 int sum[4000001],maxl[4000001],maxr[4000001],maxn[4000001];
 16 int root,sz;
 17 bool lazy[4000001],rev[4000001];
 18 inline void clear(int x){
 19     f[x]=ch[x][0]=ch[x][1]=size[x]=key[x]=sum[x]=0;
 20     lazy[x]=rev[x]=maxl[x]=maxr[x]=0;
 21     maxn[x]=-1000000000;
 22 }
 23 inline int get(int x){
 24     return ch[f[x]][1]==x;
 25 }
 26 inline int my_max(int a,int b){
 27     return a>b?a:b;
 28 }
 29 inline void swp(int &a,int &b){
 30     a^=b;
 31     b^=a;
 32     a^=b;
 33 }
 34 inline void update(int x){
 35     int l(ch[x][0]),r(ch[x][1]);
 36     sum[x]=sum[l]+sum[r]+key[x];
 37     size[x]=size[l]+size[r]+1;
 38     maxn[x]=maxl[r]+key[x]+maxr[l];
 39     if(l)
 40         maxn[x]=my_max(maxn[x],maxn[l]);
 41     if(r)
 42         maxn[x]=my_max(maxn[x],maxn[r]);
 43     maxl[x]=my_max(maxl[l],sum[l]+key[x]+maxl[r]);
 44     maxr[x]=my_max(maxr[r],sum[r]+key[x]+maxr[l]);
 45 }
 46 inline void pushdown(int x){
 47     int l(ch[x][0]),r(ch[x][1]);
 48     if(lazy[x]){
 49         rev[x]=lazy[x]=0;
 50         if(l){
 51             lazy[l]=1;
 52             key[l]=key[x];
 53             sum[l]=key[l]*size[l];
 54         }
 55         if(r){
 56             lazy[r]=1;
 57             key[r]=key[x];
 58             sum[r]=key[r]*size[r];
 59         }
 60         if(key[x]>=0){
 61             if(l)
 62                 maxl[l]=maxr[l]=maxn[l]=sum[l];
 63             if(r)
 64                 maxl[r]=maxr[r]=maxn[r]=sum[r];
 65         }
 66         else{
 67             if(l){
 68                 maxl[l]=maxr[l]=0;
 69                 maxn[l]=key[l];
 70             }
 71             if(r){
 72                 maxl[r]=maxr[r]=0;
 73                 maxn[r]=key[r];
 74             }
 75         }
 76     }
 77     if(rev[x]){
 78         rev[x]=0;
 79         rev[l]^=1;
 80         rev[r]^=1;
 81         swp(maxl[l],maxr[l]);
 82         swp(maxl[r],maxr[r]);
 83         swp(ch[l][0],ch[l][1]);
 84         swp(ch[r][0],ch[r][1]);
 85     }
 86 }
 87 inline void rotate(int x){
 88     int p(f[x]),g(f[p]),which(get(x));
 89     pushdown(p);
 90     pushdown(x);
 91     ch[p][which]=ch[x][which^1];
 92     f[ch[p][which]]=p;
 93     ch[x][which^1]=p;
 94     f[p]=x;
 95     f[x]=g;
 96     if(g)
 97         ch[g][ch[g][1]==p]=x;
 98     update(p);
 99     update(x);
100 }
101 inline void splay(int x,int y){
102     pushdown(x);
103     for(int fa=f[x];fa!=y;rotate(x),fa=f[x])
104         if(f[fa]!=y)
105             rotate(get(fa)==get(x)?fa:x);
106     if(!y)
107         root=x;
108 }
109 inline int find(int x){
110     int now(root);
111     while(1){
112         pushdown(now);
113         if(x<=size[ch[now][0]])
114             now=ch[now][0];
115         else{
116             int tmp(size[ch[now][0]]+1);
117             if(x<=tmp)
118                 return now;
119             x-=tmp;
120             now=ch[now][1];
121         }
122     }
123 }
124 inline void build(int l,int r,int fa){
125     if(l>r)
126         return ;
127     if(l==r){
128         f[l]=fa;
129         size[l]=1;
130         sum[l]=key[l];
131         if(key[l]>=0)
132             maxl[l]=maxr[l]=maxn[l]=key[l];
133         else{
134             maxl[l]=maxr[l]=0;
135             maxn[l]=key[l];
136         }
137         if(fa){
138             if(l<fa)
139                 ch[fa][0]=l;
140             else
141                 ch[fa][1]=l;
142         }
143         return;
144     }
145     int mid((l+r)>>1);
146     build(l,mid-1,mid);
147     build(mid+1,r,mid);
148     f[mid]=fa;
149     update(mid);
150     if(fa){
151         if(mid<fa)
152             ch[fa][0]=mid;
153         else
154             ch[fa][1]=mid;
155     }
156 }
157 inline void erase(int x){
158     if(!x)
159         return;
160     erase(ch[x][0]);
161     erase(ch[x][1]);
162     clear(x);
163 }
164 char op[10];
165 inline int gg(){
166     freopen("seq2005.in","r",stdin);
167     freopen("seq2005.out","w",stdout);
168     int n(read()),m(read());
169     key[++sz]=-1000000000;
170     for(int i=1;i<=n;i++)
171         key[++sz]=read();
172     key[++sz]=-1000000000;
173     build(1,n+2,0);
174     root=(n+3)>>1;
175     int all(n+2);
176     while(m--){//cout<<'*'<<m<<endl;
177         scanf("%s",op);
178         if(op[0]=='I'){
179             int pos(read()+1),tot(read()),old(sz+1);
180             int x(find(pos)),y(find(pos+1));
181             splay(x,0);
182             splay(y,x);
183             for(int i=1;i<=tot;i++)
184                 key[++sz]=read();
185             build(old,sz,0);
186             int rt((old+sz)>>1);
187             f[rt]=y;
188             ch[y][0]=rt;
189             update(y);
190             update(x);
191             all+=tot;
192             continue;
193         }
194         if(op[0]=='D'){
195             int pos(read()),tot(read());
196             int x(find(pos)),y(find(pos+tot+1));
197             splay(x,0);
198             splay(y,x);
199             erase(ch[y][0]);
200             update(y);
201             update(x);
202             all-=tot;
203             continue;
204         }
205         if(op[0]=='R'){
206             int pos(read()),tot(read());
207             int x(find(pos)),y(find(pos+tot+1));
208             splay(x,0);
209             splay(y,x);
210             int z(ch[y][0]);
211             if(!lazy[z]){
212                 rev[z]^=1;
213                 swp(ch[z][0],ch[z][1]);
214                 swp(maxl[z],maxr[z]);
215                 update(y);
216                 update(x);
217             }
218             continue;
219         }
220         if(op[0]=='G'){
221             int pos(read()),tot(read());
222             int x(find(pos)),y(find(pos+tot+1));
223             splay(x,0);
224             splay(y,x);
225             printf("%d
",sum[ch[y][0]]);
226             continue;
227         }
228         if(op[2]=='K'){
229             int pos(read()),tot(read()),c(read());
230             int x(find(pos)),y(find(pos+tot+1));
231             splay(x,0);
232             splay(y,x);
233             int z(ch[y][0]);
234             lazy[z]=1;
235             key[z]=c;
236             sum[z]=size[z]*c;
237             if(c>=0)
238                 maxl[z]=maxr[z]=maxn[z]=sum[z];
239             else{
240                 maxl[z]=maxr[z]=0;
241                 maxn[z]=c;
242             }
243             update(y);
244             update(x);
245         }
246         if(op[2]=='X'){
247             int x(find(1)),y(find(all));
248             splay(x,0);
249             splay(y,x);
250             printf("%d
",maxn[ch[y][0]]);
251         }
252     }
253     return 0;
254 }
255 int K(gg());
256 int main(){;}
View Code

然后成功在COGS上A了,然后我去了HZOJ、洛谷什么的。

MLE喵喵喵???我难道交了个MLE自动机喵喵喵???

//MLE自动机
int main(){
    while(1)
        long long *x=new long long[500];
}
//请不要作死在自己电脑上以及他人电脑上使用

最后我发现,COGS上的限制是这样的:

时间限制:3 s   内存限制:256 MB

然而其他OJ的限制是这样的:

时间限制: 1 Sec  内存限制: 64 MB

数组就莫名GG了= =

所以我学(xiu)习(gai)了某司机的指针板子,成功的get√到了新板子= =

264行SpalySplay板子奉上

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<vector>
  6 using namespace std;
  7 inline int read(){
  8     int sum(0),f(1);
  9     char ch(getchar());
 10     for(;ch<'0'||ch>'9';ch=getchar())
 11         if(ch=='-')
 12             f=-1;
 13     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
 14     return sum*f;
 15 }
 16 const int inf(0x2FFFFFFF);
 17 inline int my_max(int a,int b){
 18     return a>b?a:b;
 19 }
 20 inline void swp(int &a,int &b){
 21     a^=b;
 22     b^=a;
 23     a^=b;
 24 }
 25 class SplayTree{
 26     private:
 27         class Node{
 28             public:
 29                 int k,sz,sm,lm,rm,ms;
 30                 bool set,rev;
 31                 Node *fa,*ch[2];
 32                 Node(const int& key){
 33                     this->k=key;
 34                     this->sm=key;
 35                     this->ms=key;
 36                     this->lm=key>=0?key:0;
 37                     this->rm=key>=0?key:0;
 38                     this->sz=1;
 39                     this->fa=NULL;
 40                     this->ch[0]=NULL;
 41                     this->ch[1]=NULL;
 42                     this->rev=false;
 43                     this->set=false;
 44                 }
 45                 ~Node(){
 46                     if(this->ch[0]!=NULL)
 47                         delete this->ch[0];
 48                     if(this->ch[1]!=NULL)
 49                         delete this->ch[1];
 50                 }
 51                 inline void pushup(){
 52                     if(this!=NULL){
 53                         this->sz=this->ch[0]->size()+this->ch[1]->size()+1;
 54                         this->sm=this->ch[0]->sum()+this->ch[1]->sum()+this->k;
 55                         this->lm=my_max(this->ch[0]->lmax(),this->ch[0]->sum()+this->k+this->ch[1]->lmax());
 56                         this->rm=my_max(this->ch[1]->rmax(),this->ch[1]->sum()+this->k+this->ch[0]->rmax());
 57                         this->ms=my_max(my_max(this->ch[0]->maxsum(),this->ch[1]->maxsum()),this->ch[0]->rmax()+this->k+this->ch[1]->lmax());
 58                     }
 59                 }
 60                 inline void Swap(){
 61                     if(this!=NULL){
 62                         this->rev=!this->rev;
 63                         swp(this->lm,this->rm);
 64                         swap(this->ch[0],this->ch[1]);
 65                     }
 66                 }
 67                 inline void Set(const int &key){
 68                     if(this!=NULL){
 69                         this->set=true;
 70                         this->k=key;
 71                         this->sm=key*this->sz;
 72                         this->lm=my_max(this->sm,0);
 73                         this->rm=my_max(this->sm,0);
 74                         this->ms=my_max(this->sm,this->k);
 75                     }
 76                 }
 77                 inline void pushdown(){
 78                     if(this->set){
 79                         this->set=this->rev=false;
 80                         this->ch[0]->Set(this->k);
 81                         this->ch[1]->Set(this->k);
 82                     }
 83                     if(this->rev){
 84                         this->rev=false;
 85                         this->ch[0]->Swap();
 86                         this->ch[1]->Swap();
 87                     }
 88                 }
 89                 inline int sum(){
 90                     return this?this->sm:0;
 91                 }
 92                 inline int maxsum(){
 93                     return this?this->ms:-inf;
 94                 }
 95                 inline int key(){
 96                     return this?this->k:0;
 97                 }
 98                 inline int lmax(){
 99                     return this?this->lm:0;
100                 }
101                 inline int rmax(){
102                     return this?this->rm:0;
103                 }
104                 inline int size(){
105                     return this?this->sz:0;
106                 }
107         }*root;
108         inline void rotate(Node *root,int k){
109             Node *tmp(root->ch[k^1]);
110             root->pushdown();
111             tmp->pushdown();
112             tmp->fa=root->fa;
113             if(root->fa==NULL)
114                 this->root=tmp;
115             else
116                 if(root->fa->ch[0]==root)
117                     root->fa->ch[0]=tmp;
118                 else
119                     root->fa->ch[1]=tmp;
120             root->ch[k^1]=tmp->ch[k];
121             if(tmp->ch[k]!=NULL)
122                 tmp->ch[k]->fa=root;
123             tmp->ch[k]=root;
124             root->fa=tmp;
125             root->pushup();
126             tmp->pushup();
127         }
128         inline void Splay(Node *root,Node *fa=NULL){
129             while(root->fa!=fa){
130                 int k(root->fa->ch[0]==root);
131                 if(root->fa->fa==fa)
132                     rotate(root->fa,k);
133                 else{
134                     int d(root->fa->fa->ch[0]==root->fa);
135                     rotate(k==d?root->fa->fa:root->fa,k);
136                     rotate(root->fa,d);
137                 }
138             }
139         }
140         inline Node* build(const vector<int> &v,int l,int r){
141             if(l>r)
142                 return NULL;
143             int mid((l+r)>>1);
144             Node *tmp(new Node(v[mid]));
145             tmp->ch[0]=build(v,l,mid-1);
146             tmp->ch[1]=build(v,mid+1,r);
147             if(tmp->ch[0]!=NULL)
148                 tmp->ch[0]->fa=tmp;
149             if(tmp->ch[1]!=NULL)
150                 tmp->ch[1]->fa=tmp;
151             tmp->pushup();
152             return tmp;
153         }
154     public:
155         SplayTree():root(new Node(-inf)){
156             this->root->ch[1]=new Node(-inf);
157             this->root->ch[1]->fa=this->root;
158         }
159         SplayTree(const vector<int> &v){
160             this->root=build(v,0,v.size()-1);
161         }
162         ~SplayTree(){
163             delete this->root;
164         }
165         Node* Kth(int pos){
166             ++pos;
167             Node* root(this->root);//cout<<'+';
168             while(root!=NULL){
169                 root->pushdown();
170                 int k(root->ch[0]->size()+1);
171                 if(pos<k)
172                     root=root->ch[0];
173                 else
174                     if(pos==k)
175                         return root;
176                     else{
177                         pos-=k;
178                         root=root->ch[1];
179                     }
180             }
181             return NULL;
182         }
183         inline int Sum(const int &pos,const int &len){
184             this->Splay(this->Kth(pos-1));
185             this->Splay(this->Kth(pos+len),this->root);
186             return this->root->ch[1]->ch[0]->sum();
187         }
188         inline void Reverse(const int &pos,const int &len){
189             this->Splay(this->Kth(pos-1));
190             this->Splay(this->Kth(pos+len),this->root);
191             this->root->ch[1]->ch[0]->Swap();
192             this->root->ch[1]->pushup();
193             this->root->pushup();
194         }
195         inline void Set(const int &pos,const int &len,const int &d){
196             this->Splay(this->Kth(pos-1));
197             this->Splay(this->Kth(pos+len),this->root);
198             this->root->ch[1]->ch[0]->Set(d);
199             this->root->ch[1]->pushup();
200             this->root->pushup();
201         }
202         inline void Insert(const int &pos,SplayTree *data){
203             this->Splay(this->Kth(pos));
204             this->Splay(this->Kth(pos+1),this->root);
205             Node *tmp(data->root);
206             data->root=NULL;
207             this->root->ch[1]->ch[0]=tmp;
208             tmp->fa=this->root->ch[1];
209             this->root->ch[1]->pushup();
210             this->root->pushup();
211         }
212         inline void Delete(const int &pos,const int &len){
213             this->Splay(this->Kth(pos-1));
214             this->Splay(this->Kth(pos+len),this->root);
215             delete this->root->ch[1]->ch[0];
216             this->root->ch[1]->ch[0]=NULL;
217             this->root->ch[1]->pushup();
218             this->root->pushup();
219         }
220         inline int maxsum(){
221             return this->root->maxsum();
222         }
223 };
224 SplayTree *tree(new SplayTree());
225 vector<int>v;
226 char op[20];
227 int x,y;
228 inline int gg(){
229     freopen("seq2005.in","r",stdin);
230     freopen("seq2005.out","w",stdout);
231     int n(read()),m(read());
232     for(int i=0;i<n;i++)
233         v.push_back(read());
234     tree->Insert(0,new SplayTree(v));//cout<<'*';
235     while(m--){
236         scanf("%s",op);
237         if(op[0]!='M'||op[2]!='X')
238             x=read(),y=read();
239         if(op[0]=='G')
240             printf("%d
",tree->Sum(x,y));
241         else
242             if(op[0]=='D')
243                 tree->Delete(x,y);
244             else
245                 if(op[0]=='R')
246                     tree->Reverse(x,y);
247                 else
248                     if(op[0]=='I'){
249                         v.clear();
250                         while(y--)
251                             v.push_back(read());
252                         tree->Insert(x,new SplayTree(v));
253                     }
254                     else
255                         if(op[0]=='M'){
256                             if(op[2]=='K')
257                                 tree->Set(x,y,read());
258                             else
259                                 printf("%d
",tree->maxsum());
260                         }
261     }
262 }
263 int K(gg());
264 int main(){;}
View Code

这题,真的虐心啊= =

原文地址:https://www.cnblogs.com/hzoi-mafia/p/7289215.html