dsu on tree 求调
查看原帖
dsu on tree 求调
483928
Z1qqurat楼主2023/3/19 21:43

WA on #9,思路大概是用一个 multimap 维护目前的名字,hash_table 是用来把名字转化为权值的。

#include <bits/stdc++.h>
#include <bits/extc++.h>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
const int N = 2e5 + 5;
int n, q, fr, rt[N], sz[N], dep[N], hsn[N], vis[N], cnt, a[N], heavy, ans[N];
multiset <int> s;
gp_hash_table <string, int> hs;
struct Qr{
    int Dep, id;
};
vector <int> G[N];
vector <Qr> qr[N];

void dfs1(int u, int ff) {
    sz[u] = 1;
    for (int v : G[u]) {
        if(v == ff) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
        if(sz[v] > sz[hsn[u]]) hsn[u] = v;
    }
    return ;
}

void update(int u, int ff, int val) {
    if(val == 1) {
        if(s.find(a[u]) == s.end()) vis[dep[u]]++;
        s.insert(a[u]);
    }
    else {
        s.erase(s.find(a[u]));
        if(s.find(a[u]) == s.end()) vis[dep[u]]--;
    }
    for (int v : G[u]) {
        if(v == ff || v == heavy) continue;
        update(v, u, val);
    }
    return ;
}

void dfs2(int u, int ff, int ish) {
    for (int v : G[u]) {
        if(v == ff || v == hsn[u]) continue;
        dfs2(v, u, 0);
    }
    if(hsn[u]) dfs2(hsn[u], u, 1), heavy = hsn[u];
    update(u, ff, 1);
    for (int i = 0; i < qr[u].size(); ++i) ans[qr[u][i].id] = vis[qr[u][i].Dep];
    heavy = 0;
    if(!ish) update(u, ff, -1);
    return ;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        string s; int r; cin >> s; scanf("%d", &r);
        if(!hs[s]) hs[s] = ++cnt;
        a[i] = hs[s];
        if(r == 0) rt[++fr] = i;
        else G[r].emplace_back(i);
    }
    for (int i = 1; i <= fr; ++i) dfs1(rt[i], 0);
    scanf("%d", &q);
    for (int i = 1; i <= q; ++i) {
        int x, y; scanf("%d%d", &x, &y);
        qr[x].emplace_back((Qr){dep[x] + y, i});
    }
    for (int i = 1; i <= fr; ++i) dfs2(rt[i], 0, 0);
    for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
    return 0;
}
2023/3/19 21:43
加载中...