1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
| #include <algorithm> #include <cctype> #include <cstdio> #include <cstring> #include <stack> #include <vector>
template <typename T> inline T& read(T& x) { x = 0; bool f = false; short ch = getchar(); while (!isdigit(ch)) { if (ch == '-') f = true; ch = getchar(); } while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ '0'), ch = getchar(); if (f) x = -x; return x; }
const int N = 7e4 + 5; int n, m, heads[N], e_cnt, dep[N], siz[N], fa[N], son[N], top[N], ans[N];
struct Edge { int nxt, v; Edge() {} Edge(int u, int v) : nxt(u), v(v) {} } e[N << 1];
void add(int u, int v) { e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt; }
void dfs1(int u, int f) { fa[u] = f, dep[u] = dep[f] + 1, siz[u] = 1; for (int j = heads[u], v; j; j = e[j].nxt) if ((v = e[j].v) != f) { dfs1(v, u), siz[u] += siz[v]; if (siz[son[u]] < siz[v]) son[u] = v; } }
void dfs2(int u, int Top) { top[u] = Top; if (son[u]) dfs2(son[u], Top); for (int j = heads[u], v; j; j = e[j].nxt) if ((v = e[j].v) != fa[u] && v != son[u]) dfs2(v, v); }
inline int getlca(int x, int y) { while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) std::swap(x, y); x = fa[top[x]]; } return dep[x] < dep[y] ? x : y; }
inline int getdis(int x, int y) { return dep[x] + dep[y] - (dep[getlca(x, y)] << 1); }
struct Node { int a, b, w; Node() {} Node(int a, int b, int w) : a(a), b(b), w(w) {}
inline void operator()(const Node& rhs) { int tmp = getdis(a, rhs.a), orib = this->b; if (w < tmp) this->b = rhs.a, this->w = tmp; tmp = getdis(a, rhs.b); if (w < tmp) this->b = rhs.b, this->w = tmp; tmp = getdis(orib, rhs.a); if (w < tmp) this->a = orib, this->b = rhs.a, this->w = tmp; tmp = getdis(orib, rhs.b); if (w < tmp) this->a = orib, this->b = rhs.b, this->w = tmp; if (w < rhs.w) *this = rhs; } };
struct Segtree { struct UFSNode { Node s; int fa, dep; } p[N];
struct Node { int u; UFSNode p0; Node(int u, const UFSNode& p0) : u(u), p0(p0) {} };
std::vector<Edge> E[N << 2]; std::stack<Node> stk;
void insert(int x, int l, int r, int L, int R, const Edge& e) { if (L <= l && r <= R) return E[x].emplace_back(e); int mid = (l + r) >> 1; if (L <= mid) insert(x << 1, l, mid, L, R, e); if (mid < R) insert(x << 1 | 1, mid + 1, r, L, R, e); }
int find(int u) { return u == p[u].fa ? u : find(p[u].fa); }
inline void merge(int u, int v, int& len) { u = find(u), v = find(v); if (u == v) return; if (p[u].dep > p[v].dep) std::swap(u, v); stk.push(Node(u, p[u])), stk.push(Node(v, p[v])); p[v].s(p[u].s), p[u].fa = v; if (p[u].dep == p[v].dep) ++p[v].dep; len = std::max(len, p[v].s.w); }
void solve(int x, int l, int r, int len) { size_t ori = stk.size(); for (auto& i : E[x]) merge(i.nxt, i.v, len); if (l == r) ans[l] = len; else { int mid = (l + r) >> 1; solve(x << 1, l, mid, len); solve(x << 1 | 1, mid + 1, r, len); } while (stk.size() != ori) { p[stk.top().u] = stk.top().p0; stk.pop(); } } } seg;
int main() { #ifndef ONLINE_JUDGE #ifdef LOCAL freopen64("/tmp/CodeTmp/testdata.in", "r", stdin); freopen64("/tmp/CodeTmp/testdata.out", "w", stdout); #else freopen("External.in", "r", stdin); freopen("External.out", "w", stdout); #endif #endif
read(n), read(m); for (int i = 1, u, v, l, r; i < n; ++i) { read(u), read(v), read(l), read(r); add(u, v), add(v, u); seg.insert(1, 1, n, l, r, Edge(u, v)); } dfs1(1, 0), dfs2(1, 1); for (int i = 1; i <= n; ++i) seg.p[i].fa = i, seg.p[i].dep = 1, seg.p[i].s = Node(i, i, 0); seg.solve(1, 1, n, 0); for (int i = 1, x; i <= m; ++i) printf("%d\n", ans[read(x)]); return 0; }
|