玄关求调
查看原帖
玄关求调
539211
lzyqwq楼主2023/9/14 21:47

rt,树剖套平衡树,本题 85pts,弱化版 45pts,快哭了

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#define G __gnu_pbds
#define TOSNU tree_order_statistics_node_update
#define rnk order_of_key
#define lb lower_bound 
#define pii pair<int, int>
#define P make_pair 
#define fi first 
#define se second
#define vec vector
#define umap unordered_map
using namespace std; const int N = 1e5 + 5, inf = 1e9; typedef string str;
vec<int> g[N]; vector<pii> bin; vec<str> a[N]; str op1, op2, op3;
int n, m, dep[N], top[N], fa[N], hson[N], idx, dfn[N], siz[N];
umap<str, G::tree<pii, G::null_type, less<pii>, G::rb_tree_tag, G::TOSNU>> rbt;
void dfs1(int u) {
    siz[u] = 1;
    for (int v : g[u]) 
        if (v != fa[u]) dep[v] = dep[fa[v] = u] + 1, dfs1(v), siz[u] += siz[v];
}
void dfs2(int u) {
    for (int v : g[u]) {
        if (v == fa[u]) continue;
        if ((siz[v] << 1) > siz[u]) top[hson[u] = v] = top[u];
        else top[v] = v; dfs2(v);
    }
}
void dfs3(int u) {
    dfn[u] = ++idx; int t = 0; for (str s : a[u]) rbt[s].insert(P(idx, ++t));
    if (hson[u]) dfs3(hson[u]);
    for (int v : g[u]) if (v != fa[u] && v != hson[u]) dfs3(v);
}
int LCA(int u, int v) {
    while (top[u] != top[v])
        if (dep[top[u]] > dep[top[v]]) u = fa[top[u]]; else v = fa[top[v]];
    return dep[u] < dep[v] ? u : v;
}
int chain(int u, int v, str suf) {
    int ret = 0;
    while (top[u] != top[v]) {
        ret += rbt[suf].rnk(P(dfn[u], inf)) - rbt[suf].rnk(P(dfn[top[u]], 0));
        u = fa[top[u]];
    }
    return ret + rbt[suf].rnk(P(dfn[u], inf)) - rbt[suf].rnk(P(dfn[v], 0));
}
void erase(int u, int v, str suf) {
    while (top[u] != top[v]) {
        auto l = rbt[suf].lb(P(dfn[top[u]], 0)), r = rbt[suf].lb(P(dfn[u], inf)); 
        bin.clear(); for (auto it = l; it != r; ++it) bin.emplace_back(*it);
        for (pii i : bin) rbt[suf].erase(i); u = fa[top[u]];
    }
    auto l = rbt[suf].lb(P(dfn[v],0)), r = rbt[suf].lb(P(dfn[u], inf)); 
    bin.clear(); for (auto it = l; it != r; ++it) bin.emplace_back(*it);
    for (pii i : bin) rbt[suf].erase(i);
}
int query(int u, int v, int lca, str suf) {
    if (lca == u) return chain(v, u, suf);
    if (lca == v) return chain(u, v, suf);
    return chain(u, hson[lca], suf) + chain(v, lca, suf);
}
void del(int u, int v, int lca, str suf) { 
    if (lca == u) return erase(v, u, suf), void();
    if (lca == v) return erase(u, v, suf), void();
    erase(u, hson[lca], suf), erase(v, lca, suf);
}
signed main() {
    cin.tie(0), cout.tie(0), ios::sync_with_stdio(0); cin >> n >> m;
    for (int i = 1, u, v; i < n; ++i)
        cin >> u >> v, g[u].emplace_back(v), g[v].emplace_back(u);
    for (int i = 1, x; i <= n; ++i) {
        cin >> x; for (str tmp; x--;) cin >> tmp, a[i].emplace_back(tmp);
    }
    dfs1(1), dfs2(top[1] = 1), dfs3(1);
    for (int i = 1, u, v, lca; i <= m; ++i) {
        cin >> op1 >> op2 >> u >> v; lca = LCA(u, v);
        if (op2 == "/p")
            cout << dep[u] + dep[v] - (dep[lca] << 1) << '\n';
        else {
            cin >> op3; op3 = op3.substr(2);
            cout << query(u, v, lca, op3) << '\n';
            if (op1 == "del") del(u, v, lca, op3);
        }
    }
    return 0;
}
2023/9/14 21:47
加载中...