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
|
#include <map> #include <cstdio> #include <cstring> #include <algorithm>
template <typename T> void read(T &n) { char c; for (; (c = getchar()) < '0' || c > '9'; ) ; for (n = c - '0'; (c = getchar()) >= '0' && c <= '9'; (n *= 10) += c - '0') ; }
typedef int const ic; typedef long long ll;
static ic N = 40005; static ic M = 100005; static ic K = 300; std::map <int, int> num; int nume, h[N], w[N], base[N], seq[N << 1]; int tim, st[N], ed[N], dep[N], up[N][16]; int mans, ml, mr, mvis[N], mrec[N], ans[M]; struct Edge { int v, nxt; } e[N << 1]; struct Query { int l, r, lca, id; bool operator < (const Query &q) const { return l / K == q.l / K ? r < q.r : l / K < q.l / K; } } q[M];
void add_edge(ic &u, ic &v) { e[++ nume] = (Edge) { v, h[u] }, h[u] = nume; e[++ nume] = (Edge) { u, h[v] }, h[v] = nume; }
void dfs(ic &t, ic &fa) { seq[st[t] = ++ tim] = t, dep[t] = dep[fa] + 1, up[t][0] = fa; for (int i = h[t]; i; i = e[i].nxt) if (e[i].v != fa) dfs(e[i].v, t); seq[ed[t] = ++ tim] = t; }
int get_lca(int u, int v) { if (dep[u] > dep[v]) std::swap(u, v); for (int i = 15; ~ i; -- i) if (dep[up[v][i]] >= dep[u]) v = up[v][i]; if (u == v) return u; for (int i = 15; ~ i; -- i) if (up[u][i] != up[v][i]) u = up[u][i], v = up[v][i]; return up[u][0]; }
void add(ic &u) { if (mvis[u]) { -- mrec[w[u]], mvis[u] = 0; if (! mrec[w[u]]) -- mans; } else { if (! mrec[w[u]]) ++ mans; ++ mrec[w[u]], mvis[u] = 1; } }
void get(ic &l, ic &r) { for (; ml < l;) add(seq[ml ++]); for (; ml > l;) add(seq[-- ml]); for (; mr < r;) add(seq[++ mr]); for (; mr > r;) add(seq[mr --]); }
int main() { int n, m; read(n), read(m); for (int i = 1; i <= n; ++ i) { read(w[i]); if (! num.count(w[i])) num[w[i]] = num.size(); w[i] = num[w[i]]; } for (int i = 1, u, v; i < n; ++ i) read(u), read(v), add_edge(u, v); dfs(1, 0); for (int i = 1; i < 16; ++ i) for (int j = 1; j <= n; ++ j) up[j][i] = up[up[j][i - 1]][i - 1]; for (int i = 1, u, v; i <= m; ++ i) { read(u), read(v), q[i].id = i; if (st[u] > st[v]) std::swap(u, v); if (ed[u] > ed[v]) q[i].l = st[u] + 1, q[i].r = st[v], q[i].lca = u; else q[i].l = ed[u], q[i].r = st[v], q[i].lca = get_lca(u, v); } std::sort(q + 1, q + m + 1); mans = ml = mr = mvis[1] = mrec[w[1]] = 1; for (int i = 1; i <= m; ++ i) get(q[i].l, q[i].r), add(q[i].lca), ans[q[i].id] = mans, add(q[i].lca); for (int i = 1; i <= m; ++ i) printf("%d\n", ans[i]); return 0; }
|