题解 CF375D 【Tree and Queries】

首先,子树上的查询问题可以通过$DFS$序转为序列问题

再一看,没有修改,可以离线,这不就是莫队吗?

我们用$sum_i$表示出现次数$\geq i$的个数

用$val_i$表示第$i$种颜色的出现次数

那么每次修改时只要$O(1)$修改$sum$和$val$即可

详见代码

  1 #include <bits/stdc++.h>
  2 const int MaxN = 100010;
  3 struct node
  4 {
  5     int val, dfn, r, id;
  6 };
  7 struct query
  8 {
  9     int l, r;
 10     int pos, id, k;
 11 };
 12 struct edge
 13 {
 14     int next, to;
 15 };
 16 node a[MaxN];
 17 query q[MaxN];
 18 edge e[MaxN << 1];
 19 int n, m, cnt, dfscnt, size;
 20 int head[MaxN], ans[MaxN], sum[MaxN], val[MaxN];
 21 inline int comp(node a, node b) { return a.dfn < b.dfn; }
 22 inline int cmp(query a, query b)
 23 {
 24     if (a.pos != b.pos)
 25         return a.pos < b.pos;
 26     return a.r < b.r;
 27 }
 28 inline void add_edge(int u, int v)
 29 {
 30     ++cnt;
 31     e[cnt].to = v;
 32     e[cnt].next = head[u];
 33     head[u] = cnt;
 34 }
 35 inline void dfs(int u)
 36 {
 37     a[u].dfn = ++dfscnt;
 38     for (int i = head[u]; i; i = e[i].next)
 39     {
 40         int v = e[i].to;
 41         if (!a[v].dfn)
 42             dfs(v);
 43     }
 44     a[u].r = dfscnt;
 45 }
 46 inline int read()
 47 {
 48     int x = 0;
 49     char ch = getchar();
 50     while (ch > '9' || ch < '0')
 51         ch = getchar();
 52     while (ch <= '9' && ch >= '0')
 53         x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
 54     return x;
 55 }
 56 inline void add(int x) { ++val[a[x].val], ++sum[val[a[x].val]]; }
 57 inline void del(int x) { --sum[val[a[x].val]], --val[a[x].val]; }
 58 inline void solve()
 59 {
 60     int l = 1, r = 0;
 61     for (int i = 1; i <= m; i++)
 62     {
 63         while (l > q[i].l)
 64             --l, add(l);
 65         while (r < q[i].r)
 66             ++r, add(r);
 67         while (l < q[i].l)
 68             del(l), ++l;
 69         while (r > q[i].r)
 70             del(r), --r;
 71         ans[q[i].id] = sum[q[i].k];
 72     }
 73 }
 74 int main()
 75 {
 76     n = read(), m = read();
 77     size = pow(n, 0.55);
 78     for (int i = 1; i <= n; i++)
 79         a[i].val = read(), a[i].id = i;
 80     for (int i = 1; i <= n - 1; i++)
 81     {
 82         int u = read(), v = read();
 83         add_edge(u, v);
 84         add_edge(v, u);
 85     }
 86     dfs(1);
 87     for (int i = 1; i <= m; i++)
 88     {
 89         int v, k;
 90         v = read(), k = read();
 91         q[i].l = a[v].dfn, q[i].r = a[v].r, q[i].k = k;
 92         q[i].id = i, q[i].pos = (q[i].l - 1) / size + 1;
 93     }
 94     std::sort(q, q + m + 1, cmp);
 95     std::sort(a + 1, a + n + 1, comp);
 96     solve();
 97     for (int i = 1; i <= m; i++)
 98         printf("%d\n", ans[i]);
 99     return 0;
100 }
View Code

猜你喜欢

转载自www.cnblogs.com/little-sun0331/p/10352735.html