The main effect of the topic
Given an n-n-point tree, for each point, find out how far it is from K K.
Data Constraint
n≤10000 n\leq10000
First two points an answer, now want to quickly find how many distance is less than or equal to two points of the answer.
So first the point of the tree, and then run in the tree, each time in a row of the distance in the queue two points.
Time complexity: O (nlog3n) O (nlog^3n) SRC
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <
Algorithm> #include <vector> using namespace std;
#define N 10000 + const int MAXN = 15;
struct Note {vector < int > dis;} tp;
Vector < int > P[n];
Vector < note > Q[n];
BOOL Vis[n];
int node[2*n], next[2*n], len[2*n], head[n], tot;
int size[n], maxs[n], pre[n], cnt[n], from[n];
int deep[n], dist[n], F[N][MAXN];
int all, Root, MINV, ans;
int n;
void link (int u, int v, int w) {Node[++tot] = V;
Len[tot] = W;
Next[tot] = Head[u];
Head[u] = tot;
} void GetSize (int x, int F) {size[x] = maxs[x] = 1;
for (int p = head[x]; p; p = Next[p]) {if (node[p] = F | | vis[node[p]) continue;
GetSize (Node[p], x);
SIZE[X] + = size[node[p]];
if (Size[node[p]] > Maxs[x]) maxs[x] = size[node[p]]; } void Getroot (int x, int F) {maxs[x] = mAx (maxs[x], Size[all]-maxs[x]);
if (Maxs[x] < MINV) MINV = maxs[x], Root = x;
for (int p = head[x]; p; p = Next[p]) {if (node[p] = F | | vis[node[p]) continue;
Getroot (Node[p], x); } void DFS1 (int x, int F) {for (int p = head[x]; p; p = Next[p]) {if (node[p] = f | | vis[node[p]]
) continue;
DIST[NODE[P]] = dist[x] + len[p];
P[root].push_back (Dist[node[p]]);
DFS1 (Node[p], x);
} void DFS2 (int x, int F) {tp.dis.push_back (dist[x]);
for (int p = head[x]; p; p = Next[p]) {if (node[p] = F | | vis[node[p]) continue;
DIST[NODE[P]] = dist[x] + len[p];
DFS2 (Node[p], x);
} void DIV (int x, int F, int h) {getsize (x, 0);
MINV = 0x7fffffff;
Root = all = x;
Getroot (x, 0);
Pre[root] = F;
Vis[root] = 1;
Dist[root] = 0;
From[root] = h;
P[root].push_back (0); for (int p = HEad[root]; P;
p = next[p]) {if (Vis[node[p]]) continue;
DIST[NODE[P]] = Dist[root] + len[p];
P[root].push_back (Dist[node[p]]);
DFS1 (Node[p], 0);
Sort (P[root].begin (), P[root].end ());
int now = Root;
for (int p = head[now]; p; p = Next[p]) {if (vis[node[p)]) continue;
DIST[NODE[P]] = len[p];
Tp.dis.clear ();
DFS2 (Node[p], 0);
Sort (Tp.dis.begin (), Tp.dis.end ());
Q[now].push_back (TP);
DIV (Node[p], now, Cnt[now]);
Cnt[now] + +;
} void Search (int x) {for (int p = head[x]; p. p = next[p]) {if (node[p) = = F[x][0]) continue;
DEEP[NODE[P]] = deep[x] + 1;
DIST[NODE[P]] = dist[x] + len[p];
F[node[p]][0] = x;
Search (Node[p]);
} int LCA (int x, int y) {if (Deep[x] < deep[y]) swap (x, y); for (int i = MAXN-1 i >= 0; I--) {if (deep[f[x)[i]] >= deep[y]) x = F[x][i];
} if (x = = y) return x;
for (int i = MAXN-1 i >= 0; I--) {if (F[x][i]!= f[y][i]) x = f[x][i], y = f[y][i];
return f[x][0];
int getdist (int x, int y) {return dist[x] + dist[y]-2 * DIST[LCA (x,y)];
int Count (vector < int > P, int val) {int ret = Upper_bound (P.begin (), P.end (), Val)-P.begin ();
return ret;
int Calc (int x, int len) {int ret = 0;
int now = x, last = 0;
while (now) {int del = Getdist (now, x);
ret = Count (P[now], Len-del);
if (last) ret-= Count (Q[now][from[last]].dis, Len-del);
last = Now;
now = Pre[now];
return ret;
int main () {freopen ("treekth.in", "R", stdin);
Freopen ("Treekth.out", "w", stdout);
scanf ("%d", &n);
for (int i = 1; i < n; i + +) {int u, V, W; scanf ("%d%d%d", &u, &v, &amP;W);
Link (U, v, W);
Link (V, u, W);
DIV (1, 0, 0);
DEEP[1] = dist[1] = 0;
Search (1);
for (int j = 1; J < MAXN J + +) {for (int i = 1; I <= n; i + +) f[i][j] = f[f[i][j-1]][j-1];
for (int i = 1; I <= n; i + +) {int K;
scanf ("%d", &k);
ans =-1;
int L = 0, r = 1e9;
while (L <= r) {int mid = (L + r)/2;
if (Calc (i, mid) >= K) ans = Mid, r = mid-1;
else L = mid + 1;
printf ("%d\n", ans);
return 0; }
above.