标签:
解题思路:终于把这道splay神题A掉了,splay专题也算是告一段落了,这个题主要的坑点,还是旋转和区间合并结合。
解题代码:
1 // File Name: hysbz1500.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月10日 星期五 10时41分03秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #include<climits> 25 #define LL int 26 #define INF INT_MAX 27 #define maxn 500005 28 using namespace std; 29 30 struct SplayTree{ 31 int sz[maxn]; 32 int ch[maxn][2]; 33 int pre[maxn]; 34 int root , top1,top2; 35 int ss[maxn],que[maxn]; 36 37 void Rotate(int x, int f){ 38 int y = pre[x]; 39 push_down(y); 40 push_down(x); 41 ch[y][!f] = ch[x][f]; 42 pre[ch[x][f]] = y ; 43 pre[x] = pre[y]; 44 if(pre[x]) ch[pre[y]][ch[pre[y]][1] == y] = x; 45 ch[x][f] = y; 46 pre[y] = x; 47 push_up(y); 48 } 49 void Splay(int x, int goal){ 50 push_down(x); 51 while(pre[x] != goal){ 52 if(pre[pre[x]] == goal){ 53 Rotate(x,ch[pre[x]][0] == x); 54 }else { 55 int y = pre[x],z = pre[y]; 56 int f = (ch[z][0] == y); 57 if(ch[y][f] == x){ 58 Rotate(x,!f),Rotate(x,f); 59 }else{ 60 Rotate(y,f),Rotate(x,f); 61 } 62 } 63 } 64 push_up(x); 65 if(goal == 0) root = x; 66 } 67 void RotateTo(int k ,int goal){ 68 int x = root; 69 push_down(x); 70 while(sz[ch[x][0]] != k ){ 71 if(k < sz[ch[x][0]]){ 72 x = ch[x][0]; 73 }else { 74 k -= (sz[ch[x][0]] + 1); 75 x = ch[x][1]; 76 } 77 push_down(x); 78 } 79 Splay(x,goal); 80 } 81 void erase(int x){ 82 int father = pre[x]; 83 int head = 0 , tail = 0 ; 84 for(que[tail ++] = x; head < tail ;head ++){ 85 ss[top2 ++] = que[head]; 86 if(ch[ que[head]][0]) que[tail ++] = ch[que[head]][0]; 87 if(ch[ que[head]][1]) que[tail ++] = ch[que[head]][1]; 88 } 89 ch[father][ch[father][1] == x] = 0 ; 90 push_up(father); 91 } 92 void update_same(int x, int c) 93 { 94 if(x == 0 ) return ; 95 cg[x] = c; 96 val[x] = c; 97 sum[x] = sz[x] * c; 98 lx[x] = rx[x] = mx[x] = max(c,c*sz[x]); 99 } 100 void update_rev(int x) 101 { 102 if(x == 0 ) 103 return; 104 rev[x] ^= 1; 105 swap(lx[x],rx[x]); 106 } 107 void push_down(int x) 108 { 109 if(cg[x] != -INF) 110 { 111 update_same(ch[x][1],cg[x]); 112 update_same(ch[x][0],cg[x]); 113 rev[x] = 0 ; 114 cg[x] = -INF; 115 }else if(rev[x] == 1) 116 { 117 swap(ch[x][0],ch[x][1]); 118 update_rev(ch[x][0]); 119 update_rev(ch[x][1]); 120 rev[x] = 0 ; 121 } 122 } 123 void push_up(int x){ 124 sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]]; 125 sum[x] = val[x] + sum[ch[x][0]] + sum[ch[x][1]] ; 126 lx[x] = rx[x] = sum[x]; 127 mx[x] = sum[x]; 128 if(ch[x][0] == 0 && ch[x][1] == 0 ){ 129 return; 130 } 131 if(ch[x][0] == 0 ){ 132 lx[x] = max(val[x],lx[x]); 133 lx[x] = max(val[x]+lx[ch[x][1]],lx[x]); 134 rx[x] = max(rx[ch[x][1]],rx[x]); 135 mx[x] = max(mx[ch[x][1]],mx[x]); 136 mx[x] = max(lx[x],mx[x]); 137 mx[x] = max(rx[x],mx[x]); 138 }else if(ch[x][1] == 0 ){ 139 lx[x] = max(lx[ch[x][0]],lx[x]); 140 rx[x] = max(val[x],rx[x]); 141 rx[x] = max(val[x] + rx[ch[x][0]],rx[x]); 142 mx[x] = max(mx[ch[x][0]],mx[x]); 143 mx[x] = max(lx[x],mx[x]); 144 mx[x] = max(rx[x],mx[x]); 145 }else{ 146 lx[x] = max(lx[ch[x][0]],lx[x]); 147 lx[x] = max(sum[ch[x][0]] + val[x],lx[x]); 148 lx[x] = max(sum[ch[x][0]] + val[x] + lx[ch[x][1]],lx[x]); 149 rx[x] = max(rx[ch[x][1]],rx[x]); 150 rx[x] = max(sum[ch[x][1]] + val[x],rx[x]); 151 rx[x] = max(sum[ch[x][1]] + val[x] + rx[ch[x][0]],rx[x]); 152 mx[x] = max(val[x],mx[x]); 153 mx[x] = max(mx[ch[x][0]],mx[x]); 154 mx[x] = max(mx[ch[x][1]],mx[x]); 155 mx[x] = max(rx[ch[x][0]]+val[x],mx[x]); 156 mx[x] = max(sum[ch[x][0]]+val[x],mx[x]); 157 mx[x] = max(lx[ch[x][1]]+val[x],mx[x]); 158 mx[x] = max(sum[ch[x][1]]+val[x],mx[x]); 159 mx[x] = max(lx[ch[x][1]] + rx[ch[x][0]] + val[x],mx[x]); 160 } 161 } 162 void NewNode(int &x , LL c){ 163 if(top2) x = ss[--top2]; 164 else x = ++ top1; 165 rev[x] = ch[x][0] = ch[x][1] = pre[x] = 0 ; 166 sz[x] = 1; 167 cg[x] = -INF; 168 val[x] = sum[x] = lx[x] = rx[x] = mx[x] = c ; 169 } 170 void build(int &x,int l ,int r ,int f){ 171 if(l > r) return ; 172 int m = (l + r) >> 1; 173 NewNode(x,num[m]); 174 build(ch[x][0],l,m-1,x); 175 build(ch[x][1],m+1,r,x); 176 pre[x] = f; 177 push_up(x); 178 } 179 void init(){ 180 rev[0] = ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0 ; 181 lx[0] = rx[0] = mx[0] = sum[0] = 0; 182 cg[0] = -INF; 183 root = top1 = 0 ; 184 NewNode(root,-1); 185 NewNode(ch[root][1],-1); 186 pre[ch[root][1]] = root; 187 sz[root] = 2; 188 push_up(root); 189 } 190 void insert(int p ,int n){ 191 for(int i =1 ;i <= n;i ++) 192 scanf("%d",&num[i]); 193 RotateTo(p,0); 194 RotateTo(p+1,root); 195 build(ch[ch[root][1]][0],1,n,ch[root][1]); 196 push_up(ch[root][1]); 197 push_up(root); 198 } 199 void Del(int p , int n){ 200 RotateTo(p-1,0); 201 RotateTo(p+n,root); 202 erase(ch[ch[root][1]][0]); 203 push_up(ch[root][1]); 204 push_up(root); 205 } 206 void make(int p , int n, LL c){ 207 RotateTo(p-1,0); 208 RotateTo(p+n,root); 209 update_same(ch[ch[root][1]][0],c); 210 push_up(ch[root][1]); 211 push_up(root); 212 } 213 void flip(int p ,int n ){ 214 RotateTo(p-1,0); 215 RotateTo(p+n,root); 216 update_rev(ch[ch[root][1]][0]); 217 } 218 LL getsum(int p ,int n){ 219 RotateTo(p-1,0); 220 RotateTo(p+n,root); 221 printf("%d\n",sum[ch[ch[root][1]][0]]); 222 } 223 LL maxsum(){ 224 RotateTo(0,0); 225 RotateTo(sz[root]-1,root); 226 LL tmx = -INF; 227 tmx = max(lx[ch[ch[root][1]][0]],tmx); 228 tmx = max(rx[ch[ch[root][1]][0]],tmx); 229 tmx = max(mx[ch[ch[root][1]][0]],tmx); 230 printf("%d\n",tmx); 231 } 232 int rev[maxn]; 233 LL val[maxn]; 234 LL sum[maxn]; 235 LL num[maxn]; 236 LL mx[maxn]; 237 LL rx[maxn]; 238 LL lx[maxn]; 239 LL cg[maxn]; 240 }spt; 241 int n , m; 242 char str[100]; 243 int ta,tb; 244 LL tc; 245 int main(){ 246 //freopen("in","r",stdin); 247 // freopen("output","w",stdout); 248 spt.init(); 249 scanf("%d %d",&n,&m); 250 spt.insert(0,n); 251 while(m--){ 252 scanf("%s",str); 253 if(str[0] == ‘G‘){ 254 scanf("%d %d",&ta,&tb); 255 spt.getsum(ta,tb); 256 }else if(str[0] == ‘I‘){ 257 scanf("%d %d",&ta,&tb); 258 spt.insert(ta,tb); 259 }else if(str[0] == ‘D‘){ 260 scanf("%d %d",&ta,&tb); 261 spt.Del(ta,tb); 262 }else if(str[0] == ‘M‘ && str[2] == ‘K‘){ 263 scanf("%d %d %d",&ta,&tb,&tc); 264 spt.make(ta,tb,tc); 265 }else if(str[0] == ‘R‘){ 266 scanf("%d %d",&ta,&tb); 267 spt.flip(ta,tb); 268 }else { 269 // spt.debug(spt.root); 270 spt.maxsum(); 271 /*spt.debug(spt.root); 272 printf("\n"); 273 spt.print(spt.root); 274 printf("\n"); 275 spt.maxsum();*/ 276 } 277 } 278 return 0; 279 }
HYSBZ 1500 [NOI2005]维修数列 splay
标签:
原文地址:http://www.cnblogs.com/zyue/p/4423582.html