Skip to content

Commit 1aa56f1

Browse files
authored
Merge pull request rachitiitr#4 from rachitkewl/master
Added HLD code
2 parents d70b712 + f998ce1 commit 1aa56f1

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed

Tree/HLD.cpp

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
#include <bits/stdc++.h>
2+
// http://www.spoj.com/problems/QTREE/
3+
using namespace std;
4+
#define gc getchar_unlocked
5+
#define fo(i,n) for(i=0;i<n;i++)
6+
#define Fo(i,k,n) for(i=k;k<n?i<n:i>n;k<n?i+=1:i-=1)
7+
#define ll long long
8+
#define si(x) scanf("%d",&x)
9+
#define sl(x) scanf("%lld",&x)
10+
#define ss(s) scanf("%s",s)
11+
#define pi(x) printf("%d\n",x)
12+
#define pl(x) printf("%lld\n",x)
13+
#define ps(s) printf("%s\n",s)
14+
#define deb(x) cout << #x << "=" << x << endl
15+
#define deb2(x, y) cout << #x << "=" << x << "," << #y << "=" << y << endl
16+
#define pb push_back
17+
#define mp make_pair
18+
#define F first
19+
#define S second
20+
#define all(x) x.begin(), x.end()
21+
#define clr(x) memset(x, 0, sizeof(x))
22+
#define sortall(x) sort(all(x))
23+
#define tr(it, a) for(auto it = a.begin(); it != a.end(); it++)
24+
#define PI 3.1415926535897932384626
25+
typedef pair<int, int> pii;
26+
typedef pair<ll, ll> pl;
27+
typedef vector<int> vi;
28+
typedef vector<ll> vl;
29+
typedef vector<pii> vpii;
30+
typedef vector<pl> vpl;
31+
typedef vector<vi> vvi;
32+
typedef vector<vl> vvl;
33+
int mpow(int base, int exp);
34+
void ipgraph(int m);
35+
void dfs(int u, int par);
36+
const int mod = 1000000007;
37+
const int N = 3e5, M = N;
38+
//=======================
39+
struct node{int v, w, i;};
40+
vector<node> g[N];
41+
int a[N], pos[N], arr[N];
42+
int sz[N], lvl[N], rep[N];
43+
int P[N][20], n;
44+
int chainNo, ptr;
45+
int chainOf[N], chainHead[N];
46+
int tree[4*N];
47+
48+
void dfs(int u, int par){
49+
sz[u] = 1;
50+
lvl[u] = 1+lvl[par];
51+
P[u][0] = par;
52+
for(node to:g[u]){
53+
int v = to.v;
54+
if (v == par) continue;
55+
rep[to.i] = v;
56+
dfs(v, u);
57+
sz[u] += sz[v];
58+
}
59+
}
60+
61+
int lca(int u, int v){
62+
int i, lg;
63+
if (lvl[u] < lvl[v]) swap(u, v);
64+
for(lg = 0; (1<<lg) <= lvl[u]; lg++);
65+
lg--;
66+
for(i=lg; i>=0; i--){
67+
if (lvl[u] - (1<<i) >= lvl[v])
68+
u = P[u][i];
69+
}
70+
if (u == v) return u;
71+
for(i=lg; i>=0; i--){
72+
if (P[u][i] != -1 and P[u][i] != P[v][i])
73+
u = P[u][i], v = P[v][i];
74+
}
75+
return P[u][0];
76+
}
77+
void init(){
78+
int i, j;
79+
Fo(i, 0, n+1) g[i].clear();
80+
ptr = 0, chainNo = 1;
81+
sz[0] = arr[0] = 0;
82+
lvl[0] = -1;
83+
Fo(i, 0, n+1) {
84+
chainHead[i] = -1;
85+
pos[i] = arr[i] = 0;
86+
Fo(j, 0, 20) P[i][j] = -1;
87+
}
88+
}
89+
int range_query(int rt, int lo, int hi, int x, int y){
90+
if(lo == x and hi == y) return tree[rt];
91+
int l = 2*rt, r = l+1, mid = (lo+hi)>>1;
92+
if(y <= mid) return range_query(l, lo, mid, x, y);
93+
if(x > mid) return range_query(r, mid+1, hi, x, y);
94+
return max(range_query(l, lo, mid, x, mid), range_query(r, mid+1, hi, mid+1, y));
95+
}
96+
int query_up(int u, int v){
97+
if(u == v) return 0;
98+
if(lvl[u] < lvl[v]) swap(u, v);
99+
int uchain, vchain = chainOf[v];
100+
int ans = 0;
101+
while(1){
102+
uchain = chainOf[u];
103+
if(uchain == vchain){
104+
if(u == v) return ans;
105+
ans = max(ans, range_query(1, 0, ptr, pos[v]+1, pos[u]));
106+
return ans;
107+
}
108+
ans = max(ans, range_query(1, 0, ptr, pos[chainHead[uchain]], pos[u]));
109+
u = chainHead[uchain];
110+
u = P[u][0];
111+
}
112+
return ans;
113+
}
114+
void hld(int u, int cost, int par){
115+
if(chainHead[chainNo] == -1)
116+
chainHead[chainNo] = u;
117+
chainOf[u] = chainNo;
118+
pos[u] = ++ptr;
119+
arr[ptr] = cost;
120+
int sc = 0, w;
121+
for(node to: g[u]){
122+
int v = to.v;
123+
if(v == par) continue;
124+
if(sz[sc] < sz[v])sc = v, w = to.w;
125+
}
126+
if(sc) hld(sc, w, u);
127+
for(node to: g[u]){
128+
int v = to.v;
129+
if(v == par or v == sc) continue;
130+
chainNo++;
131+
hld(v, to.w, u);
132+
}
133+
}
134+
void build(int rt, int lo, int hi){
135+
if(lo == hi){
136+
tree[rt] = arr[lo];
137+
return;
138+
}
139+
int l = 2*rt, r = l+1, mid = (lo+hi)>>1;
140+
build(l, lo, mid);
141+
build(r, mid+1, hi);
142+
tree[rt] = max(tree[l], tree[r]);
143+
}
144+
void update(int rt, int lo, int hi, int pos, int val){
145+
if(lo == hi){
146+
tree[rt] = val;
147+
return;
148+
}
149+
int l = 2*rt, r = l+1, mid = (lo+hi)>>1;
150+
if(pos<=mid) update(l, lo, mid, pos, val);
151+
else update(r, 1+mid, hi, pos, val);
152+
tree[rt] = max(tree[l], tree[r]);
153+
}
154+
155+
int query(int u, int v){
156+
int w = lca(u, v);
157+
int ans = max(query_up(u, w), query_up(v, w));
158+
return ans;
159+
}
160+
void change(int i, int val){
161+
int u = rep[i];
162+
update(1, 0, ptr, pos[u], val);
163+
}
164+
void compute(){
165+
int i, j;
166+
dfs(1, 0);
167+
for(i=1; i<20; i++){
168+
Fo(j, 1, n+1)
169+
if (P[j][i-1] != -1)
170+
P[j][i] = P[P[j][i-1]][i-1];
171+
}
172+
hld(1, 0, 0);
173+
//make segment tree now
174+
assert(ptr == n);
175+
build(1, 0, ptr);
176+
}
177+
void solve(){
178+
int i;
179+
si(n);
180+
init();
181+
int u, v, w;
182+
char s[10];
183+
fo(i, n-1){
184+
si(u);
185+
si(v);
186+
si(w);
187+
g[u].pb({v, w, i+1});
188+
g[v].pb({u, w, i+1});
189+
}
190+
compute();
191+
ss(s);
192+
while(1){
193+
if(s[0] == 'D') break;
194+
si(u); si(v);
195+
if(s[0] == 'C'){
196+
change(u, v);
197+
}
198+
else{
199+
pi(query(u, v));
200+
}
201+
ss(s);
202+
}
203+
}
204+
int main()
205+
{
206+
ios_base::sync_with_stdio(false);
207+
cin.tie(NULL);
208+
int i,k,j;
209+
int t;
210+
si(t);
211+
while(t--) solve();
212+
return 0;
213+
}

0 commit comments

Comments
 (0)