codeforces 375D . Tree and Queries 启发式合并 || dfs序+莫队

题目链接

一个n个节点的树, 每一个节点有一个颜色, 1是根节点。 m个询问, 每个询问给出u, k。 输出u的子树中出现次数大于等于k的颜色的数量。

启发式合并, 先将输入读进来, 然后dfs完一个节点就处理跟它有关的询问。

感觉不是很难, 然而.....WA了n次最后还是看的别人的代码

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <map>
  8 #include <set>
  9 #include <string>
 10 #include <queue>
 11 #include <stack>
 12 #include <bitset>
 13 using namespace std;
 14 #define pb(x) push_back(x)
 15 #define ll long long
 16 #define mk(x, y) make_pair(x, y)
 17 #define lson l, m, rt<<1
 18 #define mem(a) memset(a, 0, sizeof(a))
 19 #define rson m+1, r, rt<<1|1
 20 #define mem1(a) memset(a, -1, sizeof(a))
 21 #define mem2(a) memset(a, 0x3f, sizeof(a))
 22 #define rep(i, n, a) for(int i = a; i<n; i++)
 23 #define fi first
 24 #define se second
 25 typedef pair<int, int> pll;
 26 const double PI = acos(-1.0);
 27 const double eps = 1e-8;
 28 const int mod = 1e9+7;
 29 const int inf = 1061109567;
 30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
 31 const int maxn = 1e5+5;
 32 int head[maxn*2], num, id[maxn], val[maxn], ans[maxn];
 33 struct node
 34 {
 35     int to, nextt, w;
 36 }e[maxn*2];
 37 void add(int u, int v) {
 38     e[num].to = v, e[num].nextt = head[u], head[u] = num++;
 39 }
 40 void init() {
 41     num = 0;
 42     mem1(head);
 43 }
 44 struct Node
 45 {
 46     map <int, int> mp;
 47     vector <int> ve;
 48     int sz = 0;
 49     void add(int x) {
 50         mp[x]++;
 51         while(mp[x]>=ve.size()) {
 52             ve.push_back(0);
 53         }
 54         ve[mp[x]]++;
 55         sz++;
 56     }
 57 }st[maxn];
 58 vector <pll> v[maxn];
 59 void combine(int& x, int& y) {
 60     if(st[x].sz<st[y].sz)
 61         swap(x, y);
 62     for(auto it = st[y].mp.begin(); it!=st[y].mp.end(); it++) {
 63         for(int i = 0; i<it->second; i++) {
 64             st[x].add(it->first);
 65         }
 66     }
 67 }
 68 void dfs(int u, int fa) {
 69     st[u].add(val[u]);
 70     for(int i = head[u]; ~i; i = e[i].nextt) {
 71         int vx = e[i].to;
 72         if(vx == fa)
 73             continue;
 74         dfs(vx, u);
 75         combine(id[u], id[vx]);
 76     }
 77     for(int i = 0; i<v[u].size(); i++) {
 78         int x = v[u][i].fi, y = v[u][i].se;
 79         if(x>=st[id[u]].ve.size())
 80             continue;
 81         ans[y] = st[id[u]].ve[x];
 82     }
 83 }
 84 int main()
 85 {
 86     int n, m, x, y;
 87     cin>>n>>m;
 88     init();
 89     for(int i = 1; i<=n; i++) {
 90         scanf("%d", &val[i]);
 91         id[i] = i;
 92     }
 93     for(int i = 0; i<n-1; i++) {
 94         scanf("%d%d", &x, &y);
 95         add(x, y);
 96         add(y, x);
 97     }
 98     for(int i = 0; i<m; ++i) {
 99         scanf("%d%d", &x, &y);
100         v[x].pb(mk(y, i));
101     }
102     dfs(1, 0);
103     for(int i = 0; i<m; i++)
104         cout<<ans[i]<<endl;
105     return 0;
106 }
原文地址:https://www.cnblogs.com/yohaha/p/5094464.html