1. 程式人生 > >uoj#349 【WC2018】即時戰略

uoj#349 【WC2018】即時戰略

pos splay turn targe 我們 $1 type sample 次數

題目鏈接

正解:$link-cut \ tree$。

這道題我在考場上從看題到放棄只花了$20$多分鐘。。

爆剛$t2$無果,$12$點的鐘聲響起,我無奈地開始看這道題,然後發現了生的希望。。

只寫了二十幾分鐘,然後又滾回去剛$t2$了。。正解根本就沒去想了(雖然本來也不會。。

不得不說這道題的標算還是很妙的,我就算去想也不可能往$LCT$這方面想。。

我們每次新開一個點,就直接從根結點開始$explore$。

我們可以用$LCT$維護當前這棵樹的鏈,於是每次從現在$splay$的根結點開始往下走。

如果$explore$返回的點在左子樹,我們就往左移,在右子樹則往右移,如果不在這棵樹我們就直接跳到$explore$返回的這個點所在的樹。

可以發現,在一棵$splay$上我們最多只會移動$splay$深度次數,那麽時間復雜度和查詢復雜度也可以保證在$O(n log n)$。

註意一點,就是每次找到目標點以後都要通過$access$來保證復雜度,以及鏈的情況需要特判。

  1 // RTS sample program
  2 #include <bits/stdc++.h>
  3 #include "rts.h"
  4 #define il inline
  5 #define RG register
  6 #define N (300005)
  7 
  8 using namespace
std; 9 10 int ch[N][2],fa[N],l[N],r[N],p[N],vis[N],lst,nxt,n; 11 12 deque<int> Q; 13 deque<int>::iterator it; 14 15 il void work(){ 16 Q.push_back(p[1]); 17 for (RG int i=2,x,v,op;i<=n;++i){ 18 if (vis[p[i]]) continue; 19 v=explore(p[1],p[i]); 20
if (nxt==v){ 21 op=2,it=Q.end(),x=*(--it); 22 while (1){ 23 v=explore(x,p[i]),vis[v]=1; 24 op==1?Q.push_front(v):Q.push_back(v); 25 if (v==p[i]) break; x=v; 26 } 27 } else if (lst==v){ 28 op=1,it=Q.begin(),x=*it; 29 while (1){ 30 v=explore(x,p[i]),vis[v]=1; 31 op==1?Q.push_front(v):Q.push_back(v); 32 if (v==p[i]) break; x=v; 33 } 34 } else{ 35 if (!lst) op=1,lst=v; else op=2,nxt=v; 36 op==1?Q.push_front(v):Q.push_back(v); 37 vis[v]=1; if (v==p[i]) continue; x=v; 38 while (1){ 39 v=explore(x,p[i]),vis[v]=1; 40 op==1?Q.push_front(v):Q.push_back(v); 41 if (v==p[i]) break; x=v; 42 } 43 } 44 } 45 return; 46 } 47 48 il int isroot(RG int x){ 49 return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x; 50 } 51 52 il void pushup(RG int x){ 53 l[x]=ch[x][0]?l[ch[x][0]]:x; 54 r[x]=ch[x][1]?r[ch[x][1]]:x; return; 55 } 56 57 il void rotate(RG int x){ 58 RG int y=fa[x],z=fa[y],k=ch[y][0]==x; 59 if (!isroot(y)) ch[z][ch[z][1]==y]=x; 60 fa[x]=z,ch[y][k^1]=ch[x][k],fa[ch[x][k]]=y; 61 ch[x][k]=y,fa[y]=x,pushup(y),pushup(x); return; 62 } 63 64 il void splay(RG int x){ 65 while (!isroot(x)){ 66 RG int y=fa[x],z=fa[y]; 67 if (!isroot(y)) rotate((ch[z][0]==y)^(ch[y][0]==x)?x:y); 68 rotate(x); 69 } 70 return; 71 } 72 73 il void access(RG int x){ 74 RG int t=0; 75 while (x){ 76 splay(x),ch[x][1]=t; 77 pushup(x),t=x,x=fa[x]; 78 } 79 return; 80 } 81 82 void play(int _n, int T, int dataType) { 83 srand(19260817+3),n=_n; 84 for (RG int i=1;i<=n;++i) p[i]=i; 85 random_shuffle(p+2,p+n+1); 86 if (dataType==3){ work(); return; } 87 for (RG int i=1;i<=n;++i) l[i]=r[i]=i; 88 for (RG int i=2,x,v;i<=n;++i){ 89 if (vis[p[i]]) continue; x=p[1]; 90 while (x!=p[i]){ 91 splay(x); 92 while (1){ 93 v=explore(x,p[i]); 94 if (v==r[ch[x][0]]) x=ch[x][0]; 95 else if (v==l[ch[x][1]]) x=ch[x][1]; 96 else{ 97 if (!vis[v]) vis[v]=1,fa[v]=x; 98 x=v; break; 99 } 100 } 101 } 102 access(x); 103 } 104 return; 105 }

uoj#349 【WC2018】即時戰略