Author : Dipu Kumar Mohanto
CSE, Batch - 6
BRUR.
Problem Statement : ACM Tax
Source : UVA Live
Category : Data Structure
Algorithm : Persistent Segment Tree
Verdict : Accepted
- #include <bits/stdc++.h>
-
- using namespace std;
-
- static const int maxn = 1e6 + 5;
- static const int logn = 18;
-
- struct Node
- {
- int st;
- int lft, rgt;
- Node(int st = 0, int lft = 0, int rgt = 0) : st(st), lft(lft), rgt(rgt) {}
- } Tree[maxn];
-
- int version[maxn], NODES, N = 100000 + 5;
-
- int update(int root, int a, int b, int pos, int val)
- {
- int newNode = ++NODES;
- Tree[newNode] = Tree[root];
- if (a == b)
- {
- Tree[newNode].st += val;
- return newNode;
- }
- int mid = (a + b) >> 1;
- if (pos <= mid) Tree[newNode].lft = update(Tree[newNode].lft, a, mid, pos, val);
- else Tree[newNode].rgt = update(Tree[newNode].rgt, mid + 1, b, pos, val);
- Tree[newNode].st = Tree[ Tree[newNode].lft ].st + Tree[ Tree[newNode].rgt ].st;
- return newNode;
- }
-
- int query(int root_lca, int root_u, int root_v, int a, int b, int k)
- {
- if (a == b) return a;
- int sum = Tree[ Tree[root_u].lft ].st + Tree[ Tree[root_v].lft ].st - 2 * Tree[ Tree[root_lca].lft ].st;
- int mid = a + b >> 1;
- if (sum >= k) return query(Tree[root_lca].lft, Tree[root_u].lft, Tree[root_v].lft, a, mid, k);
- else return query(Tree[root_lca].rgt, Tree[root_u].rgt, Tree[root_v].rgt, mid+1, b, k - sum);
- }
-
- struct GNode
- {
- int v, w;
- GNode(int v = 0, int w = 0) : v(v), w(w) {}
- };
-
- vector <GNode> graph[maxn];
- int depth[maxn], father[maxn][logn];
-
- void dfs(int u = 1, int p = -1)
- {
- for (int i = 1; i < logn; i++) father[u][i] = father[ father[u][i-1] ][i-1];
- for (GNode it : graph[u])
- {
- int v = it.v;
- int w = it.w;
- if (v == p) continue;
- depth[v] = depth[u] + 1;
- father[v][0] = u;
- version[v] = update(version[u], 1, N, w, 1);
- dfs(v, u);
- }
- }
-
- int lca(int u, int v)
- {
- if (depth[u] < depth[v]) swap(u, v);
- for (int i = logn-1; i >= 0; i--) if (depth[ father[u][i] ] >= depth[v]) u = father[u][i];
- if (u == v) return u;
- for (int i = logn-1; i >= 0; i--) if (father[u][i] != father[v][i]) u = father[u][i], v = father[v][i];
- return father[u][0];
- }
-
- void clean()
- {
- NODES = 0;
- for (int i = 0; i < maxn; i++)
- {
- Tree[i] = Node();
- version[i] = 0;
- graph[i].clear();
- depth[i] = 0;
- fill(begin(father[i]), end(father[i]), 0);
- }
- }
-
- signed main()
- {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.tie(nullptr);
- cout << fixed << setprecision(1);
-
- #ifndef ONLINE_JUDGE
- freopen("in.txt", "r", stdin);
- #endif // ONLINE_JUDGE
-
-
- int tc;
- cin >> tc;
- for (int tcase = 1; tcase <= tc; tcase++)
- {
- clean();
-
- int tnode;
- cin >> tnode;
- for (int e = 1; e < tnode; e++)
- {
- int u, v, w;
- cin >> u >> v >> w;
- graph[u].emplace_back(v, w);
- graph[v].emplace_back(u, w);
- }
- version[0] = 0;
- version[1] = update(version[0], 1, N, 4, 0);
- depth[1] = 1;
- dfs();
-
- int tqeury;
- cin >> tqeury;
- for (int q = 1; q <= tqeury; q++)
- {
- int u, v;
- cin >> u >> v;
- int lcax = lca(u, v);
- int d = depth[u] + depth[v] - 2 * depth[lcax];
- int k = (d+1) / 2;
- double ans = (double)query(version[lcax], version[u], version[v], 1, N, k);
- if (~d & 1)
- {
- ans += (double)query(version[lcax], version[u], version[v], 1, N, k+1);
- ans /= 2.0;
- }
- cout << ans << '\n';
- }
- }
- }
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.