Heavy Light Decomposition (2)
Bài toán
Độ phức tạp
Code này của Nguyễn Tiến Trung Kiên
#include <stdio.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define long long long
#define f1(i,n) for (int i=1; i<=n; i++)
#define f0(i,n) for (int i=0; i<n; i++)
const int oo = 0x3c3c3c3c;
#define all(a) a.begin(), a.end()
#define N 100005
int n, m, Max[4*N];
vector<int> a[N];
struct node {
int ll, rr, id;
node (int L, int R, int X)
{ ll=L, rr=R, id=X; }
node left()
{ return node(ll, (ll+rr)/2, id*2); }
node right()
{ return node((ll+rr)/2+1, rr, id*2+1); }
void increase(int u, int Value){
if (ll>u || u>rr) return ;
if (ll==rr) { Max[id] += Value; return ; }
left().increase(u, Value);
right().increase(u, Value);
Max[id]=max(Max[id*2], Max[id*2+1]);
}
int max_range(int L, int R){
if (L>rr || ll>R || L>R) return -oo;
if (L<=ll && rr<=R) return Max[id];
int Max1 = left().max_range(L, R);
int Max2 = right().max_range(L, R);
return max(Max1, Max2);
}
};
int Size[N], Level[N], Parent[20][N];
int IndexOf[N], Head[N], Peak=0;
void previsit(int u, int p){ // end-update Size[], Level[], Parent[0][]
Size[u]=1;
for (int i=0; int v=a[u][i]; i++) if (v!=p){
Level[v]=Level[u]+1;
Parent[0][v]=u;
previsit(v, u);
Size[u]+=Size[v];
}
}
void previsit_all(){
Level[1]=1;
Parent[0][1]=0;
previsit(1, 1);
f1(k,19) f1(i,n) Parent[k][i]=Parent[k-1][Parent[k-1][i]];
}
bool as_size(int x, int y)
{ return Size[x]>Size[y]; }
void visit(int u, int p){ // end-update a[], IndexOf[], Head[]
a[u].erase(remove(all(a[u]), p), a[u].end());
sort(a[u].begin(), --a[u].end(), as_size);
for (int i=0; int v=a[u][i]; i++) {
IndexOf[v]=++Peak;
Head[v]=(i==0 ? Head[u] : v);
visit(v, u);
}
}
void visit_all(){
IndexOf[1]=++Peak;
Head[1]=1;
visit(1, 1);
}
int lca(int x, int y){
#define k(x) Parent[k][x]
for (int k=19; k>=0; k--) if (Level[k(x)]>=Level[y]) x=k(x);
for (int k=19; k>=0; k--) if (Level[k(y)]>=Level[x]) y=k(y);
for (int k=19; k>=0; k--) if (k(x)!=k(y)) { x=k(x), y=k(y); }
while (x!=y) { x=Parent[0][x], y=Parent[0][y]; }
return x;
}
int max_path(int u, int p){
int Max=-oo;
while (Level[Head[u]] >= Level[p]) {
Max = max(Max, node(1,Peak,1).max_range(IndexOf[Head[u]], IndexOf[u]));
u=Parent[0][Head[u]];
}
Max = max(Max, node(1,Peak,1).max_range(IndexOf[p], IndexOf[u]));
return Max;
}
main(){
scanf("%d", &n);
f1(i,n-1) {
int x, y;
scanf("%d%d", &x, &y);
a[x].push_back(y);
a[y].push_back(x);
}
f1(i,n) a[i].push_back(0);
previsit_all();
visit_all();
scanf("%d", &m);
f1(i,m){
char c; int x, y;
scanf(" %c%d%d", &c, &x, &y);
if (c=='I') node(1,Peak,1).increase(IndexOf[x], y);
if (c=='G') {
int p=lca(x, y);
printf("%d\n", max(max_path(x,p), max_path(y,p)));
}
}
}
Nhận xét
Tham khảo
http://acm.timus.ru/problem.aspx?space=1&num=1553