NOI2005维修数列(splay)
题目描述:
Description
请写一个程序,要求维护一个数列,支持以下 6 种操作:
请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格
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
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
10
1
10
解题思路:
听说出这道题时还没有splay,所以当时是块状链表题。
6种操作:
1.插入:
常规操作,将子树建好再把前驱后继中间空出来栽上,pushup两遍愈合即可。
PS:可以用建树时的build函数适配数组
2.删除:
将整棵树像挤痘痘一样挤出来扔掉。
PS:空间开不下,需要回收废树,不要将树分解,那样浪费时间,开一个栈,将废树压入,开新点时弹出一棵树,推入左右子树,根节点格式化输出即可。
3.修改:
常规操作,只不过用bool做懒惰标记主要是我怕它区间赋0
4.翻转:
文艺平衡树模板。
PS:pushdown时若有3的bool型标记就可以清除4的标记了。
5.求和:
维护一个sum
6.最大值:
类似vijos小白逛公园维护左连续最大值,右连续最大值,中间连续最大值即可。
PS:把0号节点的中间连续最大值赋为-∞,防止ans<0
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lll tr[spc].ch[0] 5 #define rrr tr[spc].ch[1] 6 #define ls ch[0] 7 #define rs ch[1] 8 const int N=6000001; 9 struct trnt{ 10 int ch[2]; 11 int fa; 12 bool onmi; 13 int lzt; 14 int val; 15 int sum; 16 int wgt; 17 int lmx,rmx,mmx; 18 int chd; 19 }tr[N]; 20 trnt stdtr; 21 int n,m; 22 int lne[N]; 23 int bin[N]; 24 int top=0; 25 int root; 26 int siz; 27 char cmd[100]; 28 int ins[N]; 29 int org,fin; 30 void destory(int &spc) 31 { 32 bin[++top]=spc; 33 spc=0; 34 return ; 35 } 36 int translate(void) 37 { 38 int tmp=(int)(cmd[2]); 39 if(tmp=='S') 40 return 1; 41 if(tmp=='L') 42 return 2; 43 if(tmp=='K') 44 return 3; 45 if(tmp=='V') 46 return 4; 47 if(tmp=='T') 48 return 5; 49 if(tmp=='X') 50 return 6; 51 return 0; 52 } 53 bool whc(int spc) 54 { 55 return tr[tr[spc].fa].rs==spc; 56 } 57 void pushup(int spc) 58 { 59 tr[spc].sum=tr[lll].sum+tr[rrr].sum+tr[spc].val; 60 tr[spc].wgt=tr[lll].wgt+tr[rrr].wgt+1; 61 tr[spc].lmx=std::max(tr[lll].lmx,tr[lll].sum+tr[spc].val+tr[rrr].lmx); 62 tr[spc].rmx=std::max(tr[rrr].rmx,tr[rrr].sum+tr[spc].val+tr[lll].rmx); 63 tr[spc].mmx=std::max(tr[spc].val+tr[lll].rmx+tr[rrr].lmx,std::max(tr[lll].mmx,tr[rrr].mmx)); 64 return ; 65 } 66 int apply() 67 { 68 if(top) 69 { 70 int spc=bin[top--]; 71 if(lll) 72 bin[++top]=lll; 73 if(rrr) 74 bin[++top]=rrr; 75 return spc; 76 } 77 return ++siz; 78 } 79 void address(int &spc) 80 { 81 spc=apply(); 82 tr[spc]=stdtr; 83 return ; 84 } 85 void new_point(int &spc,int mid,int *a,int f) 86 { 87 address(spc); 88 tr[spc].fa=f; 89 tr[spc].val=a[mid]; 90 return ; 91 } 92 void din(int spc,int k) 93 { 94 if(!spc) 95 return ; 96 tr[spc].onmi=true; 97 tr[spc].lzt=k; 98 tr[spc].val=k; 99 tr[spc].sum=tr[spc].wgt*k; 100 tr[spc].mmx=(k>0)?tr[spc].sum:k; 101 tr[spc].lmx=tr[spc].rmx=(k>0)?tr[spc].sum:0; 102 return ; 103 } 104 void ovt(int spc) 105 { 106 if(!spc) 107 return ; 108 tr[spc].chd^=1; 109 std::swap(lll,rrr); 110 std::swap(tr[spc].lmx,tr[spc].rmx); 111 return ; 112 } 113 void pushdown(int spc) 114 { 115 if(tr[spc].onmi) 116 { 117 din(lll,tr[spc].lzt); 118 din(rrr,tr[spc].lzt); 119 tr[spc].lzt=0; 120 tr[spc].chd=0; 121 tr[spc].onmi=false; 122 } 123 if(tr[spc].chd) 124 { 125 ovt(lll); 126 ovt(rrr); 127 tr[spc].chd=0; 128 } 129 return ; 130 } 131 void rotate(int spc) 132 { 133 int f=tr[spc].fa; 134 bool k=whc(spc); 135 tr[f].ch[k]=tr[spc].ch[!k]; 136 tr[spc].ch[!k]=f; 137 tr[tr[f].fa].ch[whc(f)]=spc; 138 tr[spc].fa=tr[f].fa; 139 tr[f].fa=spc; 140 tr[tr[f].ch[k]].fa=f; 141 pushup(f); 142 pushup(spc); 143 return ; 144 } 145 void splay(int spc,int f) 146 { 147 while(tr[spc].fa!=f) 148 { 149 int ft=tr[spc].fa; 150 if(tr[ft].fa==f) 151 { 152 rotate(spc); 153 break; 154 } 155 if(whc(spc)^whc(ft)) 156 rotate(spc); 157 else 158 rotate(ft); 159 rotate(spc); 160 } 161 if(!f) 162 root=spc; 163 return ; 164 } 165 void build(int l,int r,int &spc,int f,int *a) 166 { 167 if(l>r) 168 return ; 169 int mid=(l+r)>>1; 170 new_point(spc,mid,a,f); 171 if(l==r) 172 { 173 tr[spc].lmx=tr[spc].rmx=(a[mid]>0)?a[mid]:0; 174 tr[spc].mmx=a[mid]; 175 tr[spc].wgt=1; 176 tr[spc].sum=a[mid]; 177 if(l==0) 178 org=spc; 179 if(l==n+1) 180 fin=spc; 181 } 182 build(l,mid-1,lll,spc,a); 183 build(mid+1,r,rrr,spc,a); 184 pushup(spc); 185 if(l==r) 186 tr[spc].mmx=tr[spc].val; 187 return ; 188 } 189 int place(int spc,int rnk) 190 { 191 pushdown(spc); 192 if(tr[lll].wgt>=rnk) 193 return place(lll,rnk); 194 if(tr[lll].wgt+1==rnk) 195 return spc; 196 return place(rrr,rnk-tr[lll].wgt-1); 197 } 198 int main() 199 { 200 scanf("%d%d",&n,&m); 201 for(int i=1;i<=n;i++) 202 scanf("%d",&lne[i]); 203 build(0,n+1,root,0,lne); 204 tr[0].mmx=-0x3f3f3f3f; 205 while(m--) 206 { 207 scanf("%s",cmd); 208 int opr=translate(); 209 if(opr==1) 210 { 211 int tmproot; 212 int pos,tot; 213 scanf("%d%d",&pos,&tot); 214 for(int i=1;i<=tot;i++) 215 scanf("%d",&ins[i]); 216 build(1,tot,tmproot,0,ins); 217 splay(place(root,pos+1),0); 218 splay(place(root,pos+2),root); 219 tr[tr[root].rs].ls=tmproot; 220 tr[tmproot].fa=tr[root].rs; 221 pushup(tr[root].rs); 222 pushup(root); 223 }else if(opr==2) 224 { 225 int pos,tot; 226 scanf("%d%d",&pos,&tot); 227 splay(place(root,pos),0); 228 splay(place(root,pos+tot+1),root); 229 destory(tr[tr[root].rs].ls); 230 pushup(tr[root].rs); 231 pushup(root); 232 }else if(opr==3) 233 { 234 int pos,tot,c; 235 scanf("%d%d%d",&pos,&tot,&c); 236 splay(place(root,pos),0); 237 splay(place(root,pos+tot+1),root); 238 pushdown(root); 239 pushdown(tr[root].rs); 240 int spc=tr[tr[root].rs].ls; 241 din(spc,c); 242 pushup(tr[root].rs); 243 pushup(root); 244 }else if(opr==4) 245 { 246 int pos,tot; 247 scanf("%d%d",&pos,&tot); 248 splay(place(root,pos),0); 249 splay(place(root,pos+tot+1),root); 250 pushdown(root); 251 pushdown(tr[root].rs); 252 int spc=tr[tr[root].rs].ls; 253 ovt(spc); 254 pushup(tr[root].rs); 255 pushup(root); 256 }else if(opr==5) 257 { 258 int pos,tot; 259 scanf("%d%d",&pos,&tot); 260 splay(place(root,pos),0); 261 splay(place(root,pos+tot+1),root); 262 int spc=tr[tr[root].rs].ls; 263 printf("%d\n",tr[spc].sum); 264 }else{ 265 splay(place(root,1),0); 266 splay(place(root,tr[root].wgt),root); 267 printf("%d\n",tr[tr[tr[root].rs].ls].mmx); 268 } 269 } 270 return 0; 271 }