noi 2005 维护数列 平衡树
非常恶心的一道数据结构题。
1 #include<iostream> 2 #include<cmath> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 #define MAXN 510000 7 #define INF 9876 8 struct node 9 { 10 node *left,*right,*father; 11 int value,size,sum,ml,mr,max; 12 bool change,rev; 13 }; 14 node *root,*nul; 15 int top=0,n,m; 16 int a[MAXN]; 17 void update(node *x) 18 { 19 if(x==nul) 20 return ; 21 x->size=x->left->size+x->right->size+1; 22 x->sum=x->left->sum+x->right->sum+x->value; 23 x->ml=max(x->left->ml,max(x->left->sum+x->value,x->left->sum+x->value+x->right->ml)); 24 x->mr=max(x->right->mr,max(x->right->sum+x->value,x->right->sum+x->value+x->left->mr)); 25 x->max=max(max(x->left->max,x->right->max),x->value); 26 x->max=max(max(x->left->mr+x->value,x->right->ml+x->value),max(x->max,x->left->mr+x->right->ml+x->value)); 27 } 28 void push_down(node *x) 29 { 30 if(x==nul) 31 return ; 32 if(x->change) 33 { 34 x->change=0; 35 x->right->change=x->left->change=1; 36 x->left->value=x->right->value=x->value; 37 if(x->left!=nul) 38 { 39 x->left->sum=x->left->max=x->left->ml=x->left->mr=x->value*x->left->size; 40 if(x->value<0) 41 x->left->max=x->left->ml=x->left->mr=x->value; 42 } 43 if(x->right!=nul) 44 { 45 x->right->sum=x->right->max=x->right->ml=x->right->mr=x->value*x->right->size; 46 if(x->value<0) 47 x->right->max=x->right->ml=x->right->mr=x->value; 48 } 49 50 } 51 if(x->rev) 52 { 53 x->rev=0; 54 swap(x->left,x->right); 55 x->left->rev=!x->left->rev; 56 x->right->rev=!x->right->rev; 57 swap(x->left->ml,x->left->mr); 58 swap(x->right->ml,x->right->mr); 59 } 60 } 61 62 void dfs(node *t) 63 { 64 if(t->left!=nul) 65 dfs(t->left); 66 if(t->right!=nul) 67 dfs(t->right); 68 delete t; 69 } 70 void left_rotate(node *x) 71 { 72 node *y=x->father,*z=x->left; 73 if(y==y->father->left) y->father->left=x; 74 else y->father->right=x; 75 x->father=y->father; 76 x->left=y; 77 y->father=x; 78 y->right=z; 79 z->father=y; 80 update(y); update(x); 81 } 82 void right_rotate(node *x) 83 { 84 node *y=x->father,*z=x->right; 85 if(y==y->father->right) y->father->right=x; 86 else y->father->left=x; 87 x->father=y->father; 88 x->right=y; 89 y->father=x; 90 y->left=z; 91 z->father=y; 92 update(y); update(x); 93 } 94 void splay(node *rootnew,node *x) 95 { 96 push_down(x); 97 node *fa=rootnew->father; 98 while(x->father!=fa) 99 { 100 node *y=x->father; 101 node *z=y->father; 102 if(z==fa) 103 { 104 if(x==y->left) 105 right_rotate(x); 106 else 107 left_rotate(x); 108 break; 109 } 110 if(y==z->left) 111 if(x==y->left) right_rotate(y),right_rotate(x); 112 else left_rotate(x),right_rotate(x); 113 else 114 if(x==y->left) right_rotate(x),left_rotate(x); 115 else left_rotate(y),left_rotate(x); 116 } 117 if(rootnew==root) 118 root=x; 119 } 120 void find(int pos,node *root) 121 { 122 node *x=root; 123 while(push_down(x),x->left->size+1!=pos) 124 { 125 if(x->left->size>=pos) 126 x=x->left; 127 else 128 pos-=x->left->size+1,x=x->right; 129 } 130 splay(root,x); 131 } 132 node* newnode(int value,node *f) 133 { 134 node *p=new node; 135 p->value=value; 136 p->size=1; p->father=f; 137 p->sum=p->max=p->ml=p->mr=value; 138 p->change=p->rev=0; 139 p->left=p->right=nul; 140 return p; 141 } 142 void insert(int pos,int tot,int a[]) 143 { 144 node *p,*t; 145 p=t=newnode(a[1],nul); 146 for(int i=2;i<=tot;i++) 147 p=p->right=newnode(a[i],p); 148 find(pos+1,root); 149 find(1,root->right); 150 root->right->left=t; 151 t->father=root->right; 152 splay(root,p); 153 } 154 void del(int pos,int tot) 155 { 156 find(pos,root); 157 find(tot+1,root->right); 158 dfs(root->right->left); 159 root->right->left=nul; 160 update(root->right); 161 splay(root,root->right); 162 } 163 void change(int pos,int tot,int value) 164 { 165 find(pos,root); 166 find(tot+1,root->right); 167 root->right->left->change=1; 168 root->right->left->value=value; 169 node *p=root->right->left; 170 p->sum=p->max=p->ml=p->mr=p->value*p->size; 171 if(p->value<0) 172 p->max=p->ml=p->mr=p->value; 173 splay(root,root->right->left); 174 } 175 void reverse(int pos,int tot) 176 { 177 find(pos,root); 178 find(tot+1,root->right); 179 root->right->left->rev=!root->right->left->rev; 180 swap(root->right->left->ml,root->right->left->mr); 181 splay(root,root->right->left); 182 } 183 int get_sum(int pos,int tot) 184 { 185 find(pos,root); 186 find(tot+1,root->right); 187 return root->right->left->sum; 188 } 189 int max_sum() 190 { 191 return root->max; 192 } 193 194 195 void init() 196 { 197 nul=new node; 198 node *la=new node; 199 node *lb=new node; 200 nul->value=nul->ml=nul->mr=nul->max=-INF; nul->size=nul->sum=0; 201 la->value=la->ml=la->mr=la->max=-INF; la->size=2; la->sum=0; 202 lb->value=lb->ml=lb->mr=lb->max=-INF; lb->size=1; lb->sum=0; 203 root=la; 204 la->father=nul; 205 la->left=nul; 206 la->right=lb; 207 lb->father=la; 208 lb->left=lb->right=nul; 209 } 210 211 char c[20]; 212 int main() 213 { 214 int i,j,x,y,z,pos; 215 scanf("%d%d",&n,&m); 216 for(i=1;i<=n;i++) 217 scanf("%d",a+i); 218 init(); 219 insert(0,n,a); 220 for(i=1;i<=m;i++) 221 { 222 scanf("%s",c); 223 switch(c[0]) 224 { 225 case'I': 226 scanf("%d%d",&pos,&n); 227 for(j=1;j<=n;j++) 228 scanf("%d",a+j); 229 insert(pos,n,a); 230 break; 231 case'D': 232 scanf("%d%d",&pos,&n); 233 del(pos,n); 234 break; 235 case'R': 236 scanf("%d%d",&pos,&n); 237 reverse(pos,n); 238 break; 239 case'G': 240 scanf("%d%d",&pos,&n); 241 printf("%d\n",get_sum(pos,n)); 242 break; 243 case'M': 244 if(c[2]=='K') 245 { 246 scanf("%d%d%d",&pos,&n,&x); 247 change(pos,n,x); 248 } 249 else 250 printf("%d\n",max_sum()); 251 break; 252 } 253 } 254 return 0; 255 }