/*
节点的标号从1开始
*/
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10000; //N为节点的个数
struct e{
int v;
e* nxt;
}es[N<<1], *fir[N];
struct node{
int ls, rs; //左右儿子的下标,为-1表示空
int l, r; //区间的左右标号
//数据域,根据不同的需要添加,数据的down和update和线段树的无异
int mid() { return (l + r) >> 1; }
}nodes[N<<1];
int n, en;
int que[N], par[N], dep[N], root[N], seg[N], st[N], ed[N], top[N], sons[N], id[N];
//que用于BFS,par记录父节点,dep记录节点的深度。 root[i]为链i的根节点,seg用于在链上建线段树,
//st[i],ed[i]分别为链i的左右端点,top[i]为链i的顶部的节点,sons[i]为节点i的儿子节点
//id[i]是节点i所属的链的标号,
int ln, cnt, tr; //ln是链的个数,cnt为节点的个数,tr是树的根节点
inline void add_e(int u, int v){
es[en].v = v;
es[en].nxt = fir[u];
fir[u] = &es[en++];
}
inline void newNode(int& id, int l, int r){
nodes[cnt].ls = nodes[cnt].rs = -1;
nodes[cnt].l = l;
nodes[cnt].r = r;
id = cnt++;
}
void build(int& id, int l, int r){ //在剖分出来的链上构建线段树
newNode(id, l, r);
if(l >= r){
//seg[l]为落在这个线段树节点上的原树中的节点
return ;
}
int mid = (l+r)>>1;
build(nodes[id].ls, l, mid);
build(nodes[id].rs, mid+1, r);
}
void initTree(){ //初始化剖分树
//确定父亲
int l, r, u, v, i;
e* cur;
l = r = 0;
que[r++] = tr;
par[tr] = -1;
dep[tr] = 0;
while(l != r){
u = que[l++];
int g = 1;
for(cur = fir[u]; cur; cur = cur->nxt){
if((v = cur->v) != par[u]){
que[r++] = v;
par[v] = u;
dep[v] = dep[u]+1;
}
}
}
//计算子树大小
for(i = 1; i <= n; i++){
sons[i] = 1;
id[i] = -1;
}
for(i = r-1; i >= 0; i--){
u = que[i];
if(par[u] >= 0){
sons[par[u]] += sons[u];
}
}
//剖分链
l = r = 0;
que[r++] = tr;
ln = cnt = 0;
while(l != r){
u = que[l++];
st[ln] = dep[u]; //用节点的深度作为线段树中区间的左右标号
top[ln] = u;
while(u >= 0){
id[u] = ln;
ed[ln] = dep[u];
seg[dep[u]] = u;
int best;
for(cur = fir[u], best=-1; cur; cur = cur->nxt){
if(id[v = cur->v] == -1){
if(best == -1 || (best >= 0 && sons[v] > sons[best])){
best = v;
}
}
}
if(best >= 0){
for(cur = fir[u]; cur; cur = cur->nxt){
if(id[v = cur->v] == -1 && best != v){
que[r++] = v;
}
}
}
u = best;
}
root[ln] = -1;
build(root[ln], st[ln], ed[ln]);
ln++;
}
}
void lqry(int& id, int ql, int qr){
if(id == -1) return ;
if(ql <= nodes[id].l && nodes[id].r <= qr){
return ;
}
if(nodes[id].l == nodes[id].r){
return ;
}
int mid = (nodes[id].l+nodes[id].r)>>1;
if(ql <= mid){
lqry(nodes[id].ls, ql, qr);
}
if(qr > mid){
lqry(nodes[id].rs, ql, qr);
}
}
void qry(int u, int v){ //查询u和v之间的最大值
while(id[u] != id[v]){
if(id[u] > id[v]){
swap(u, v);
}
int b = id[v];
lqry(root[b], st[b], dep[v]);
v = par[top[b]];
}
if(dep[u] > dep[v]){
swap(u, v);
}
lqry(root[id[u]], dep[u], dep[v]);
}
int main(){
return 0;
}