const int MAXN = 10010; /*******************Online & SegmentTree********************************/
const int MAXM = 10010;
struct N
{
int v,w,next;
}edge[MAXM*2];
int Top;
int head[MAXN];
int MAXSIZE;
int dep[MAXN];
int seq[MAXN*2];
int R[MAXN];
struct ST
{
int dep,point;
bool operator < (const ST &A) const
{
return dep < A.dep;
}
}st[MAXN*8];
//若为无向图则w = 1。
void Link(int u,int v,int w)
{
edge[Top].v = v;
edge[Top].w = w;
edge[Top].next = head[u];
head[u] = Top++;
}
void Init()
{
memset(head,-1,sizeof(head));
Top = 0;
MAXSIZE = 0;
}
void InitDep(int s,int pre = -1,int d = 0)
{
R[s] = ++MAXSIZE;
seq[MAXSIZE] = s;
dep[s] = d;
for(int p = head[s]; p != -1; p = edge[p].next)
{
if(edge[p].v != pre)
{
InitDep(edge[p].v,s,d+edge[p].w);
seq[++MAXSIZE] = s;
}
}
}
void InitST(int site,int l,int r)
{
if(l == r)
{
st[site].dep = dep[seq[l]];
st[site].point = seq[l];
return ;
}
int mid = (l+r)>>1;
InitST(site<<1,l,mid);
InitST(site<<1|1,mid+1,r);
st[site] = st[site<<1].dep < st[site<<1|1].dep ? st[site<<1] : st[site<<1|1];
}
ST QueryLCA(int site,int L,int R,int l,int r)
{
if(L == l && R == r)
return st[site];
int mid = (L+R)>>1;
if(r <= mid)
return QueryLCA(site<<1,L,mid,l,r);
else if(mid < l)
return QueryLCA(site<<1|1,mid+1,R,l,r);
return min(QueryLCA(site<<1,L,mid,l,mid),QueryLCA(site<<1|1,mid+1,R,mid+1,r));
}
/*********************Online & multiply**********************************/
int pa[MAXN][MAXM];
int dep[MAXN];
void InitFaDep(int s,int pre = -1,int d = 0)
{
pa[s][0] = pre;
dep[s] = d;
for(int p = head[s];p != -1; p = edge[p].next)
{
if(edge[p].v != pre)
InitFaDep(edge[p].v,s,d+1);
}
}
void InitPa(int n)
{
int i,j,t;
for(j = 1,t = 2;j < MAXM;t <<= 1,++j)
{
for(i = 1;i <= n ; ++i)
{
if(pa[i][j-1] != -1)
pa[i][j] = pa[pa[i][j-1]][j-1];
else
pa[i][j] = -1;
}
}
}
int QueryLCA(int u,int v)
{
if(dep[u] < dep[v])
swap(u,v);
for(int j = MAXM-1;j >= 0; --j)
{
if(pa[u][j] != -1 && dep[u]-(1<<j) >= dep[v])
u = pa[u][j];
}
if(u == v) return u;
for(int j = MAXM-1;j >= 0; --j)
{
if(pa[u][j] != -1 && pa[u][j] != pa[v][j])
u = pa[u][j],v = pa[v][j];
}
return pa[u][0];
}