HDU5296 Annoying problem(LCA)
1 //#pragma comment(linker, "/STACK:1677721600") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include <vector> 9 #include <cstdio> 10 #include <cctype> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 #define INF 0x3f3f3f3f 17 #define inf (-((LL)1<<40)) 18 #define lson k<<1, L, (L + R)>>1 19 #define rson k<<1|1, ((L + R)>>1) + 1, R 20 #define mem0(a) memset(a,0,sizeof(a)) 21 #define mem1(a) memset(a,-1,sizeof(a)) 22 #define mem(a, b) memset(a, b, sizeof(a)) 23 #define FIN freopen("in.txt", "r", stdin) 24 #define FOUT freopen("out.txt", "w", stdout) 25 #define rep(i, a, b) for(int i = (a); i <= (b); i ++) 26 #define dec(i, a, b) for(int i = (a); i >= (b); i --) 27 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 100000 + 100; 36 const int MAXM = 2000000 + 100; 37 const double eps = 1e-8; 38 LL MOD = 1000000007; 39 40 struct Edge { 41 int v, w; 42 Edge(int _v = 0, int _w = 0) { 43 v = _v; w = _w; 44 } 45 }; 46 47 struct LCA { 48 int idx[MAXN << 1]; 49 int dep[MAXN << 1]; 50 int dp[MAXN << 1][20]; 51 int K[MAXN << 1]; 52 int node_cnt; 53 vector<Edge>G[MAXN]; 54 int P[MAXN]; 55 56 int dis[MAXN]; 57 58 void init(int n) { 59 mem0(dep); mem0(K); 60 node_cnt = 0; 61 rep (i, 0, n) G[i].clear(); 62 } 63 void add_edge(int u, int v, int w) { 64 G[u].push_back(Edge(v, w)); 65 G[v].push_back(Edge(u, w)); 66 } 67 void dfs(int u, int fa, int height, int dist) { 68 idx[++node_cnt] = u; 69 dep[node_cnt] = height; 70 P[u] = node_cnt; 71 dis[u] = dist; 72 int sz = G[u].size(); 73 rep (i, 0, sz - 1) { 74 int v = G[u][i].v; 75 if(v == fa) continue; 76 dfs(v, u, height + 1, dist + G[u][i].w); 77 idx[++node_cnt] = u; 78 dep[node_cnt] = height; 79 } 80 } 81 void init_st_table() { 82 dfs(1, -1, 0, 0); 83 84 int n = node_cnt; 85 rep (i, 1, n) { 86 dp[i][0] = i; 87 while((1 << (K[i] + 1)) <= i) K[i] ++; 88 } 89 for(int j = 1; (1 << j) <= n; j ++) { 90 for(int i = 1; i + (1 << j) - 1 <= n; i ++) { 91 int l_pos = dp[i][j - 1], r_pos = dp[i + (1 << (j - 1))][j - 1]; 92 dp[i][j] = dep[l_pos] < dep[r_pos] ? l_pos : r_pos; 93 } 94 } 95 } 96 int rmq_query(int L, int R) { 97 if(L > R) swap(L, R); 98 int len = R - L + 1, k = K[len]; 99 return dep[dp[L][k]] < dep[dp[R - (1 << k) + 1][k]] ? dp[L][k] : dp[R - (1 << k) + 1][k]; 100 } 101 int lca_query(int u, int v) { 102 int id = rmq_query(P[u], P[v]); 103 return idx[id]; 104 } 105 }lca; 106 107 struct SegTree { 108 int s[MAXN << 3]; 109 void update(int k, int L, int R, int p, int v) { 110 if(L == R) { s[k] = v; return ; } 111 if(((L + R) >> 1) >= p) update(lson, p, v); 112 else update(rson, p, v); 113 s[k] = s[k << 1] + s[k << 1 | 1]; 114 } 115 int query_sum(int k, int L, int R, int p) { 116 if(R <= p) return s[k]; 117 if( ((L + R) >> 1) >= p ) return query_sum(lson, p); 118 return s[k << 1] + query_sum(rson, p); 119 } 120 int query_pos(int k, int L, int R, int x) { 121 if(L == R) return L; 122 if(s[k << 1] >= x) return query_pos(lson, x); 123 return query_pos(rson, x - s[k << 1]); 124 } 125 }st; 126 127 int t, n, m, cas = 0; 128 int u, v, w; 129 bool vis[MAXN << 1]; 130 131 int main() 132 { 133 // FIN; 134 cin >> t; 135 while(t--) { 136 scanf("%d %d", &n, &m); 137 lca.init(n); 138 rep (i, 2, n) { 139 scanf("%d %d %d", &u, &v, &w); 140 lca.add_edge(u, v, w); 141 } 142 lca.init_st_table(); 143 144 mem0(st.s); 145 mem0(vis); 146 int ans = 0; 147 printf("Case #%d:\n", ++cas); 148 while(m --) { 149 scanf("%d %d", &u, &v); 150 if( (u == 1 && !vis[v]) || (u == 2 && vis[v]) ) { 151 vis[v] = !vis[v]; 152 if(u == 2) st.update(1, 1, lca.node_cnt, lca.P[v], 0); 153 if( st.s[1] ) { 154 int x, y; 155 int sum = st.query_sum(1, 1, lca.node_cnt, lca.P[v]); 156 if( !sum || sum == st.s[1] ) x = 1, y = st.s[1]; 157 else x = sum, y = sum + 1; 158 x = lca.idx[st.query_pos(1, 1, lca.node_cnt, x)]; 159 y = lca.idx[st.query_pos(1, 1, lca.node_cnt, y)]; 160 int xv = lca.lca_query(x, v); 161 int yv = lca.lca_query(y, v); 162 int xy = lca.lca_query(x, y); 163 ans += (u == 1 ? 1 : -1) * (lca.dis[v] - lca.dis[xv] - lca.dis[yv] + lca.dis[xy]); 164 } 165 else ans = 0; 166 if(u == 1) st.update(1, 1, lca.node_cnt, lca.P[v], 1); 167 } 168 printf("%d\n", ans); 169 } 170 } 171 return 0; 172 }