Bzoj1500 [NOI2005]维修数列

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 12469  Solved: 3955

Description

Input

输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

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

Sample Output

-1
10
1
10

HINT

Source

Splay模板题

真·一道题写一天

每个指令都是基本操作,放在一起就迷之难写……

由于空间限制,必须要重复使用del掉的旧结点

几个WA点:

  申请新结点时,没有初始化ch[]

  序列st,ed编号记录错误,导致MAX-SUM操作转错

  pushdown只处理当前层,并把标记传给下层←会WA,非要把下一层也处理掉才行。

  pushdown没有判“当前结点为空时直接跳过”

  1 /*by SilverN*/
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<vector>
  8 using namespace std;
  9 const int INF=1e9;
 10 const int mxn=1000100;
 11 int read(){
 12     int x=0,f=1;char ch=getchar();
 13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 15     return x*f;
 16 }
 17 int stk[mxn],top;//回收结点 
 18 struct node{
 19     int ch[2];
 20     int fa,w,mk;
 21     int rx,lx,max;
 22     int size,sum;
 23     bool rev;
 24 }t[mxn];
 25 int a[mxn];//存储数值 
 26 int cnt=0;
 27 int root=0;
 28 int n,m,st,ed;
 29 void pd_cov(int rt){//区间修改
 30     if(!rt)return;
 31     t[rt].w=t[rt].mk;
 32     t[rt].sum=t[rt].size*t[rt].w;
 33     t[rt].lx=t[rt].rx=t[rt].max=max(t[rt].w,t[rt].sum);
 34     return;
 35 }
 36 void pd_rev(int rt){//区间翻转 
 37     if(!rt)return;
 38     t[rt].rev^=1;
 39     swap(t[rt].ch[0],t[rt].ch[1]);
 40     swap(t[rt].lx,t[rt].rx);//翻转左右连续和 
 41     return;
 42 }
 43 void pushdown(int x){
 44     if(!x)return;
 45     int lc=t[x].ch[0],rc=t[x].ch[1];
 46     if(t[x].mk!=-INF){
 47         t[lc].mk=t[rc].mk=t[x].mk;
 48         pd_cov(lc);pd_cov(rc);
 49         t[x].mk=-INF;
 50     }
 51     if(t[x].rev){
 52         pd_rev(lc);pd_rev(rc);
 53         t[x].rev=0;
 54     }
 55     return;
 56 }
 57 inline void pushup(int x){
 58     if(!x)return;
 59     int lc=t[x].ch[0],rc=t[x].ch[1];
 60     t[x].lx=max(t[lc].lx,t[lc].sum+t[x].w+max(0,t[rc].lx));
 61     t[x].rx=max(t[rc].rx,t[rc].sum+t[x].w+max(0,t[lc].rx));
 62     t[x].sum=t[lc].sum+t[x].w+t[rc].sum;
 63     t[x].max=max(max(t[lc].max,t[rc].max),max(t[rc].lx,0)+t[x].w+max(t[lc].rx,0));
 64     t[x].size=t[lc].size+t[rc].size+1;
 65     return;
 66 }
 67 void rotate(int x,int &k){
 68     int y=t[x].fa,z=t[y].fa,lc,rc;
 69     if(t[y].ch[0]==x)lc=0;else lc=1;
 70     rc=lc^1;
 71     if(y==k)k=x;
 72     else t[z].ch[t[z].ch[1]==y]=x;
 73     t[x].fa=z;t[y].fa=x;  t[t[x].ch[rc]].fa=y;
 74     t[y].ch[lc]=t[x].ch[rc];t[x].ch[rc]=y;
 75     pushup(y);
 76 }
 77 void relax(int x,int k){if(x!=k)relax(t[x].fa,k);pushdown(x);return;}
 78 void Splay(int x,int &k){
 79     relax(x,k);
 80     while(x!=k){
 81         int y=t[x].fa,z=t[y].fa;
 82         if(y!=k){
 83             if((t[z].ch[0]==y)^(t[y].ch[0]==x))rotate(x,k);
 84             else rotate(y,k);
 85         }
 86         rotate(x,k);
 87     }
 88     pushup(x);
 89     return;
 90 }
 91 inline void split(int x,int y){
 92     Splay(x,root);
 93     Splay(y,t[x].ch[1]);
 94     return;
 95 }
 96 inline int find(int x,int num){//查询序列中第num个数 
 97     pushdown(x);
 98     int lc=t[x].ch[0],rc=t[x].ch[1];
 99     if(t[lc].size>=num)return find(lc,num);
100     if(t[lc].size+1==num)return x;
101     return find(rc,num-t[lc].size-1);
102 }
103 inline int newnode(int x){//申请新结点 
104     int rt;
105     if(top)rt=stk[top--];else rt=++cnt;
106     t[rt].w=a[x];
107     t[rt].lx=t[rt].rx=t[rt].max=-INF;
108     t[rt].rev=0;t[rt].mk=-INF;
109     return rt;
110 }
111 int Build(int l,int r,int fa){
112     if(l>r)return 0;
113     int mid=(l+r)>>1,lc,rc;
114     int x=newnode(mid);
115     if(l<mid) t[x].ch[0]=Build(l,mid-1,x);
116         else t[x].ch[0]=0;
117     if(r>mid) t[x].ch[1]=Build(mid+1,r,x);
118         else t[x].ch[1]=0;
119     t[x].fa=fa;
120     pushup(x);
121     return x;
122 }
123 void del(int &x){
124     if(!x)return;
125     stk[++top]=x;
126     t[x].fa=0;
127     del(t[x].ch[0]),del(t[x].ch[1]);
128     x=0;
129     return;
130 }
131 void insert(int pos,int tot){
132     for(int i=1;i<=tot;i++)a[i]=read();
133     int tmp=Build(1,tot,0);
134     int x=find(root,pos+1),y=find(root,pos+2);
135     split(x,y);
136     t[y].ch[0]=tmp;t[tmp].fa=y;
137     pushup(y);pushup(x);
138     return;
139 }
140 void msame(int pos,int tot,int c){
141     int x=find(root,pos),y=find(root,pos+tot+1);
142     split(x,y);
143     t[t[y].ch[0]].mk=c;
144     pd_cov(t[y].ch[0]);
145     pushup(y);pushup(x);
146     return;
147 }
148 void reverse(int pos,int tot){
149     int x=find(root,pos),y=find(root,pos+tot+1);
150     split(x,y);
151     pd_rev(t[y].ch[0]);
152     pushup(y);pushup(x);
153     return;
154 }
155 void solvedel(int pos,int tot){
156     int x=find(root,pos),y=find(root,pos+tot+1);
157     split(x,y);
158     del(t[y].ch[0]);
159     pushup(y);pushup(x);
160     return;
161 }
162 inline int getmax(int pos,int tot){
163     split(st,ed);
164     return t[t[ed].ch[0]].max;
165 }
166 inline int getsum(int pos,int tot){
167     int x=find(root,pos),y=find(root,pos+tot+1);
168     split(x,y);
169     return t[t[y].ch[0]].sum;
170 }
171 void DEBUG(){
172     printf("root:%d
",root);
173     for(int i=1;i<=cnt;i++){
174         printf("id:%d  fa:%d lc:%d rc:%d w:%d
",i,t[i].fa,t[i].ch[0],t[i].ch[1],t[i].w);
175         printf("  lx:%d rx:%d mx:%d
",t[i].lx,t[i].rx,t[i].max);
176         printf("  size:%d
",t[i].size);
177     }
178     return;
179 }
180 int main(){
181     int i,j,x,y,c;
182     n=read();m=read();
183     for(i=1;i<=n;i++)a[i+1]=read();
184     st=1;ed=n+2;
185     a[st]=a[ed]=0;
186     t[0].lx=t[0].rx=t[0].max=-INF;
187     root=Build(1,n+2,0);
188     st=find(root,st);ed=find(root,ed);//记录头尾结点的编号 
189     char op[15];
190     while(m--){
191         scanf("%s",op);
192         switch(op[0]){
193             case 'I':x=read();y=read();insert(x,y);break;
194             case 'D':{x=read();y=read();solvedel(x,y);break;}
195             case 'M':{
196                 if(op[2]=='K'){x=read();y=read();c=read();msame(x,y,c);}
197                 else{printf("%d
",getmax(st,ed));}
198                 break;
199             }
200             case 'R':{x=read();y=read();reverse(x,y);break;}
201             case 'G':{x=read();y=read();printf("%d
",getsum(x,y));break;}
202             case 'B':DEBUG();break;
203         }
204     }
205     return 0;
206 }
原文地址:https://www.cnblogs.com/SilverNebula/p/6229033.html