1. 程式人生 > >bzoj 4530[BJOI2014]大融合 - LCT維護虛樹大小

bzoj 4530[BJOI2014]大融合 - LCT維護虛樹大小

小強 簡單 HA AS 格式 push hide 需要 char

BZOJ4530 [Bjoi2014]大融合

Time Limit: 30 Sec Memory Limit: 512 MB

Description

小強要在N個孤立的星球上建立起一套通信系統。這套通信系統就是連接N個點的一個樹。 這個樹的邊是一條一條添加上去的。在某個時刻,一條邊的負載就是它所在的當前能夠 聯通的樹上路過它的簡單路徑的數量。 技術分享圖片 例如,在上圖中,現在一共有了5條邊。其中,(3,8)這條邊的負載是6,因 為有六條簡單路徑2-3-8,2-3-8-7,3-8,3-8-7,4-3-8,4-3-8-7路過了(3,8)。 現在,你的任務就是隨著邊的添加,動態的回答小強對於某些邊的負載的 詢問。

Input

第一行包含兩個整數N,Q,表示星球的數量和操作的數量。星球從1開始編號。 接下來的Q行,每行是如下兩種格式之一: A x y 表示在x和y之間連一條邊。保證之前x和y是不聯通的。 Q x y 表示詢問(x,y)這條邊上的負載。保證x和y之間有一條邊。 1≤N,Q≤100000

Output

對每個查詢操作,輸出被查詢的邊的負載。

Sample Input

8 6
A 2 3
A 3 4
A 3 8
A 8 7
A 6 5
Q 3 8

Sample Output

6

這道題是一道用LCT維護虛樹大小的板子題

我們只需要單獨用一個變量存儲虛樹大小,當一個節點的一條重鏈變成輕鏈時,它的虛樹大小就加上斷開的子樹大小即可,反之減掉即可

技術分享圖片
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #define LL long long
  6 #define lc t[x].ch[0]
  7 #define rc t[x].ch[1] 
  8 
  9 using namespace std;
 10 
 11 const int MAXN = 1e5 + 10;
 12 
 13 int N, Q;
 14 char opr[10];
15 16 int s[MAXN]; 17 struct node { 18 int ch[2]; 19 int fa; 20 int lazy; 21 int size; 22 int val; 23 } t[MAXN]; 24 25 inline LL read() 26 { 27 LL x = 0, w = 1; char ch = 0; 28 while(ch < 0 || ch > 9) { 29 if(ch == -) { 30 w = -1; 31 } 32 ch = getchar(); 33 } 34 while(ch >= 0 && ch <= 9) { 35 x = x * 10 + ch - 0; 36 ch = getchar(); 37 } 38 return x * w; 39 } 40 41 void pushdown(int x) 42 { 43 if(t[x].lazy) { 44 swap(lc, rc); 45 t[lc].lazy ^= 1; 46 t[rc].lazy ^= 1; 47 t[x].lazy = 0; 48 } 49 } 50 51 bool isroot(int x) 52 { 53 return t[t[x].fa].ch[0] != x && t[t[x].fa].ch[1] != x; 54 } 55 56 void pushup(int x) 57 { 58 t[x].val = t[x].size + t[lc].val + t[rc].val + 1; 59 } 60 61 void rotate(int x) 62 { 63 int y = t[x].fa, z = t[y].fa; 64 int l, r; 65 if(!isroot(y)) { 66 if(t[z].ch[0] == y) { 67 t[z].ch[0] = x; 68 } else { 69 t[z].ch[1] = x; 70 } 71 } 72 if(t[y].ch[0] == x) { 73 l = 0; 74 } else { 75 l = 1; 76 } 77 r = l ^ 1; 78 t[y].ch[l] = t[x].ch[r], t[t[x].ch[r]].fa = y; 79 t[x].ch[r] = y, t[x].fa = z, t[y].fa = x; 80 pushup(y); 81 pushup(x); 82 } 83 84 void splay(int x) 85 { 86 int y = x; 87 int cnt = 0; 88 while(!isroot(y)) { 89 s[++cnt] = y; 90 y = t[y].fa; 91 } 92 s[++cnt] = y; 93 while(cnt) { 94 pushdown(s[cnt--]); 95 } 96 while(!isroot(x)) { 97 int y = t[x].fa, z = t[y].fa; 98 if(!isroot(y)) { 99 if((t[y].ch[0] == x) ^ (t[z].ch[0] == y)) { 100 rotate(x); 101 } else { 102 rotate(y); 103 } 104 } 105 rotate(x); 106 } 107 } 108 109 void access(int x) 110 { 111 for(int y = 0; x; y = x, x = t[x].fa) { 112 splay(x); 113 t[x].size += t[rc].val; 114 rc = y; 115 t[x].size -= t[rc].val; 116 pushup(x); 117 } 118 } 119 120 void makeroot(int x) 121 { 122 access(x); 123 splay(x); 124 t[x].lazy ^= 1; 125 } 126 127 void split(int x, int y) 128 { 129 makeroot(x); 130 access(y); 131 splay(y); 132 } 133 134 void link(int x, int y) 135 { 136 makeroot(x); 137 //split(x, y); 138 t[x].fa = y; 139 t[y].size += t[x].val; 140 pushup(y); 141 } 142 143 int findroot(int x) 144 { 145 access(x), splay(x); 146 pushdown(x); 147 while(lc) { 148 x = lc; 149 pushdown(x); 150 } 151 return x; 152 } 153 154 int main() 155 { 156 N = read(), Q = read(); 157 for(int i = 1; i <= N; i++) { 158 t[i].val = 1; 159 } 160 for(int i = 1; i <= Q; i++) { 161 scanf("%s", opr); 162 int x = read(), y = read(); 163 if(opr[0] == A) { 164 link(x, y); 165 } else { 166 split(x, y); 167 LL ans = (t[x].size + 1) * (t[y].size + 1); 168 printf("%lld\n", ans); 169 } 170 } 171 }
View Code

bzoj 4530[BJOI2014]大融合 - LCT維護虛樹大小