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 }

 

posted @ 2015-07-23 21:00  再见~雨泉  阅读(739)  评论(0编辑  收藏  举报