//点和线段树都从1开始
//边使用vector
vector<int> G[maxn];
int dfs_clock,que[maxn*2],num[maxn],iii[maxn],b[maxn],a[maxn],top[maxn],deep[maxn],fa[maxn],idx[maxn];
//采用静态链表
//a[i] 是初始时树上每个点的权值
//b[i] 是经过bfs后每个点的权值
//idx[i] 是每个点在全局线段树中的下标
void build_List()
{
int ft = 0, rear = 0;
que[rear++] = 1;
fa[1] = 0;
deep[1] = 1;
while(ft < rear)
{
int u = que[ft++];
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(v == fa[u]) continue;
fa[v] = u;
que[rear++] = v;
deep[v] = deep[u]+1;
}
}
memset(num, 0, sizeof num);
for(int i = n-1; i >= 0; i--)
{
int u = que[i];
num[u]++;
num[fa[u]] += num[u];
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j < G[i].size(); j++) if(G[i][j] != fa[i])
if(G[i][0] == fa[i] || num[G[i][j]] > num[G[i][0]])
swap(G[i][0], G[i][j]);
}
top[1] = 1;
for(int i = 1; i < n; i++)
{
int u = que[i];
if(G[fa[u]][0] == u) top[u] = top[fa[u]];
else top[u] = u;
}
memset(iii, 0, sizeof iii);
ft = 0;
dfs_clock = 0;
que[++ft] = 1;
idx[1] = ++dfs_clock;
b[1] = a[1];
while(ft)
{
int u = que[ft];
if(iii[u] >= G[u].size()) ft--;
else if(G[u][iii[u]] == fa[u]) iii[u]++;
else
{
int v = G[u][iii[u]];
que[++ft] = v;
idx[v] = ++dfs_clock;
b[idx[v]] = a[v];
iii[u]++;
}
}
}