HDU5773-The All-purpose Zero-多校#41010-最长上升子序列问题
只想到了朴素的n^2做法,然后发现可以用splay维护。于是调了几个小时的splay。。。
splay的元素是从第二个开始的!第一个是之前插入的头节点!
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 using namespace std; 6 7 #define Key_value ch[ch[root][1] ][0] 8 9 const int maxn = 5e5+10; 10 const int INF = 0x3f3f3f3f; 11 12 int pre[maxn],ch[maxn][2],key[maxn],sz[maxn]; 13 int root,tot1; 14 int rev[maxn],ma[maxn],add[maxn]; 15 int s[maxn],tot2; 16 int a[maxn]; 17 //int n,q; 18 19 void Treavel(int x) 20 { 21 if(x) 22 { 23 Treavel(ch[x][0]); 24 printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d size= %2d ma=%2d add=%2d\n",x,ch[x][0],ch[x][1],pre[x],key[x],sz[x],ma[x],add[x]); 25 Treavel(ch[x][1]); 26 } 27 } 28 void debug() 29 { 30 printf("root:%d\n",root); 31 Treavel(root); 32 } 33 // 34 35 void NewNode(int &r,int father,int k) 36 { 37 if(tot2) r = s[tot2--]; 38 else r = ++tot1; 39 pre[r] = father; 40 ch[r][0] = ch[r][1] = 0; 41 key[r] = k; 42 ma[r] = k; 43 rev[r] = add[r] = 0; 44 sz[r] = 1; 45 } 46 47 void Update_add(int r,int c) 48 { 49 if(!r) return ; 50 key[r] += c; 51 ma[r] += c; 52 add[r] += c; 53 } 54 55 void Update_rev(int r) 56 { 57 if(!r) return ; 58 swap(ch[r][0],ch[r][1]); 59 rev[r] ^= 1; 60 } 61 62 void push_up(int r) 63 { 64 int lson = ch[r][0],rson = ch[r][1]; 65 sz[r] = sz[lson] + sz[rson] + 1; 66 //ma[r] = max(max(ma[lson],ma[rson]),key[r]); 67 ma[r] = max(max(ma[lson],ma[rson]),key[r]); 68 } 69 void update_same(int r,int c) 70 { 71 if(!r) return ; 72 int lson = ch[r][0],rson = ch[r][1]; 73 key[r] = c; 74 //ma[r] = max(max(ma[lson],ma[rson]),c); 75 ma[r] = c; 76 } 77 void push_down(int r) 78 { 79 if(rev[r]) 80 { 81 Update_rev(ch[r][0]); 82 Update_rev(ch[r][1]); 83 rev[r] = 0; 84 } 85 if(add[r]) 86 { 87 Update_add(ch[r][0],add[r]); 88 Update_add(ch[r][1],add[r]); 89 add[r] = 0; 90 } 91 } 92 93 void Build(int &x,int l,int r,int father) 94 { 95 if(l>r) return ; 96 int mid = (l+r)>>1; 97 NewNode(x,father,a[mid]); 98 Build(ch[x][0],l,mid-1,x); 99 Build(ch[x][1],mid+1,r,x); 100 push_up(x); 101 } 102 103 void Init(int x) 104 { 105 root = tot1 = tot2 = 0; 106 ch[root][0] = ch[root][1] = sz[root] = pre[root] = 0; 107 rev[root] = key[root] = 0; 108 ma[root] = 0; 109 NewNode(root,0,-1); 110 NewNode(ch[root][1],root,-1); 111 //for(int i=1;i<=n;i++) scanf("%d",&a[i]); 112 a[1] = x; 113 //n = 1; 114 Build(Key_value,1,1,ch[root][1]); 115 push_up(ch[root][1]); 116 push_up(root); 117 } 118 119 void Rotate(int x,int kind) 120 { 121 int y = pre[x]; 122 push_down(y); 123 push_down(x); 124 ch[y][!kind] = ch[x][kind]; 125 pre[ch[x][kind] ] = y; 126 if(pre[y]) 127 ch[pre[y] ][ch[pre[y]][1]==y ] = x; 128 pre[x] = pre[y]; 129 ch[x][kind] = y; 130 pre[y] = x; 131 push_up(y); 132 } 133 void Splay(int r,int goal) 134 { 135 push_down(r); 136 while(pre[r] != goal) 137 { 138 if(pre[pre[r] ] == goal) 139 { 140 push_down(pre[r]); 141 push_down(r); 142 Rotate(r,ch[pre[r]][0] == r); 143 } 144 else 145 { 146 push_down(pre[pre[r] ]); 147 push_down(pre[r]); 148 push_down(r); 149 int y = pre[r]; 150 int kind = ch[pre[y] ][0] == y; 151 if(ch[y][kind] == r) 152 { 153 Rotate(r,!kind); 154 Rotate(r,kind); 155 } 156 else 157 { 158 Rotate(y,kind); 159 Rotate(r,kind); 160 } 161 } 162 push_up(r); 163 if(goal == 0) root = r; 164 } 165 } 166 167 int Get_kth(int r,int k) 168 { 169 push_down(r); 170 int t = sz[ch[r][0] ] + 1; 171 if(t == k) return r; 172 if(t > k) return Get_kth(ch[r][0],k); 173 else return Get_kth(ch[r][1],k-t); 174 } 175 176 void Insert(int pos,int x) 177 { 178 //for(int i=0;i<tot;i++) scanf("%d",&a[i]); 179 int tot = 1; 180 a[0] = x; 181 Splay(Get_kth(root,pos) , 0); 182 Splay(Get_kth(root,pos+1) , root); 183 Build(Key_value,0,tot-1,ch[root][1]); 184 push_up(ch[root][1]); 185 push_up(root); 186 } 187 void erase(int r) 188 { 189 if(!r) return ; 190 s[++tot2] = r; 191 erase(ch[r][0]); 192 erase(ch[r][1]); 193 } 194 void Delete(int pos,int tot) 195 { 196 Splay(Get_kth(root,pos) ,0); 197 Splay(Get_kth(root,pos+tot+1) , root); 198 erase(Key_value); 199 pre[Key_value] = 0; 200 Key_value = 0; 201 push_up(ch[root][1]); 202 push_up(root); 203 } 204 205 void Reverse(int pos,int tot) 206 { 207 Splay(Get_kth(root,pos) , 0); 208 Splay(Get_kth(root,pos+tot+1), root); 209 Update_rev(Key_value); 210 } 211 212 void Add(int pos,int tot,int c) 213 { 214 Splay(Get_kth(root,pos) , 0); 215 Splay(Get_kth(root,pos+tot+1) , root); 216 Update_add(Key_value,c); 217 push_up(ch[root][1]); 218 push_up(root); 219 } 220 void Make_same(int pos,int tot,int c) 221 { 222 Splay(Get_kth(root,pos) , 0); 223 Splay(Get_kth(root,pos+tot+1) , root); 224 //printf("tihuan\n"); 225 //debug(); 226 update_same(Key_value,c); 227 push_up(ch[root][1]); 228 push_up(root); 229 } 230 int Get_max(int pos,int tot) 231 { 232 Splay(Get_kth(root,pos) , 0); 233 Splay(Get_kth(root,pos+tot+1) , root); 234 push_down(root); 235 push_down(ch[root][1]); 236 return ma[Key_value]; 237 } 238 int Get_final_ans(int pos,int tot,int x) 239 { 240 int low = pos+1,high = pos+tot-1; 241 int mid; 242 while(low <= high) 243 { 244 mid = (low+high)>>1; 245 int b = key[Get_kth(root,mid)]; 246 //printf("mid:%d k:%d\n",mid,b); 247 if(x >= b) low = mid+1; 248 else high = mid -1; 249 } 250 //printf("l:%d h:%d m:%d\n",low,high,mid); 251 return (low+high)>>1; 252 } 253 254 void Revolve(int l,int r,int t) 255 { 256 if(!t) return ; 257 int c = r - t; 258 Splay(Get_kth(root,l) , 0); 259 Splay(Get_kth(root,c+2),root); 260 int tmp = Key_value; 261 Key_value = 0; 262 push_up(ch[root][1]); 263 push_up(root); 264 Splay(Get_kth(root,r-c+l) , 0); 265 Splay(Get_kth(root,r-c+l+1) , root); 266 Key_value = tmp; 267 pre[Key_value] = ch[root][1]; 268 push_up(ch[root][1]); 269 push_up(root); 270 } 271 272 int save[maxn]; 273 int T,N; 274 int LL,RR; 275 int DP(int l,int n) 276 { 277 if(n==0) return 0; 278 int i,len=1,pos; 279 Init(save[l]); 280 //debug(); 281 //printf("---\n"); 282 for(int i=l+1;i<=n;i++) 283 { 284 //printf("save:%d len:%d max:%d\n",save[i],len,Get_max(1,len)); 285 if(save[i] == 0) 286 { 287 Add(1,len,1); 288 Insert(1,0); 289 len++; 290 } 291 else if(save[i] > Get_max(1,len)) 292 { 293 //printf("max:%d\n",Get_max(1,len)); 294 Insert(len+1,save[i]); 295 len++; 296 } 297 else{ 298 pos = Get_final_ans(1,len,save[i]); 299 //printf("pos:%d\n",pos); 300 //Add(pos,1,save[i]-key[Get_kth(root,pos)]); 301 Make_same(pos,1,save[i]); 302 } 303 304 //debug(); 305 //printf("---\n"); 306 } 307 return len; 308 } 309 bool flag = false; 310 void deal() 311 { 312 int i = 1; 313 while( save[i]==0 && i <= N) i++; 314 LL = i; 315 i = N; 316 if(LL>=N ) {flag = true;return;} 317 while(save[i] == 0 && i >= 0) i--; 318 RR = i; 319 } 320 int main() 321 { 322 //freopen("input","r",stdin); 323 //freopen("splay.out","w",stdout); 324 scanf("%d",&T); 325 for(int cas=1;cas<=T;cas++) 326 { 327 scanf("%d",&N); 328 for(int i=1;i<=N;i++) 329 { 330 scanf("%d",&save[i]); 331 } 332 flag = false; 333 deal(); 334 if(flag){ 335 printf("Case #%d: %d\n",cas,N); 336 continue; 337 } 338 //printf("LL:%d RR:%d\n",LL,RR); 339 int ans = DP(LL,RR); 340 printf("Case #%d: %d\n",cas,ans+LL-1+(N-RR)); 341 } 342 } 343 /* 344 int m; 345 int main() 346 { 347 while(~scanf("%d ",&n)) 348 { 349 Init(); 350 //debug(); 351 scanf("%d ",&m); 352 char op[10]; 353 for(int i=0;i<m;i++) 354 { 355 scanf(" %s",op); 356 //printf("i:%d op:%s\n",i,op); 357 int x,y,c,t; 358 if(op[0] == 'A') //add 359 { 360 scanf("%d%d%d",&x,&y,&c); 361 Add(x,y-x+1,c); 362 } 363 else if(op[0] == 'I') //insert 364 { 365 scanf("%d",&x); 366 Insert(x,1); 367 } 368 else if(op[0] == 'D') //delete 369 { 370 scanf("%d",&x); 371 Delete(x,1); 372 } 373 else if(op[0] == 'M') //min 374 { 375 scanf("%d%d",&x,&y); 376 printf("%d\n",Get_min(x,y-x+1)); 377 } 378 else if(op[0] == 'R' && op[3] == 'E')//reverse 379 { 380 scanf("%d%d",&x,&y); 381 Reverse(x,y-x+1); 382 } 383 else //revolve 384 { 385 scanf("%d%d%d",&x,&y,&t); 386 t = (t%(y-x+1)+(y-x+1))%(y-x+1); 387 Revolve(x,y,t); 388 } 389 //debug(); 390 } 391 } 392 } 393 */