模板 树链剖分BFS版本
//点和线段树都从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]++; } } }