zoukankan      html  css  js  c++  java
  • 题解 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
    ", ans[i]);
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    Git撤销commit消息保留修改
    switchysharp设置
    Windows10下的docker安装与入门 (三) 创建自己的docker镜像并且在容器中运行它
    Windows10下的docker安装与入门 (二)使用docker引擎在容器中运行镜像
    Windows10下的docker安装与入门 (一)使用docker toolbox安装docker
    semver(Semantic Versioning)
    conda install mingw libpython
    下载 安装MYsql 服务器
    .NET(c#) 移动APP开发平台
    .NET(c#) 移动APP开发平台
  • 原文地址:https://www.cnblogs.com/little-sun0331/p/10352735.html
Copyright © 2011-2022 走看看