社区讨论

Only AC #1,2,4 求调

P4556【模板】线段树合并 / [Vani 有约会] 雨天的尾巴参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mhj2zyeg
此快照首次捕获于
2025/11/03 19:53
4 个月前
此快照最后确认于
2025/11/03 19:53
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+1, K = 18;
int n, m, a, b, x, y, z;
vector<int> e[N];
int tot, dfn[N], dep[N], fa[N], f[N][K];
void dfs(int u){
    dfn[u] = ++tot;
    f[tot][0] = u;
    for(auto v:e[u]){
        if (v==fa[u]) continue;
        fa[v] = u;
        dep[v] = dep[u]+1;
        dfs(v);
    }
}
int merge(int u, int v){return dep[u]<dep[v]?u:v;}
void initlca(){
    for(int j=1;j<K;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            f[i][j] = merge(f[i][j-1], f[i+(1<<j-1)][j-1]);
}
int lca(int u, int v){
    if (u==v) return u;
    if (dfn[u] > dfn[v]) swap(u, v);
    int l = dfn[u]+1, r = dfn[v], k = log2(r-l+1);
    return fa[merge(f[l][k], f[r-(1<<k)+1][k])];
}
struct Node{
    int cnt;
    Node *ls, *rs;
    Node() : cnt(0), ls(nullptr), rs(nullptr) {}
}*root[N];
void add(Node *&p, int l, int r, int s, int t){
    if (!p) p = new Node();
    if (l==r) {p->cnt+=t; return;}
    int mid = l + r >> 1;
    if (s <= mid) add(p->ls, l, mid, s, t);
    else add(p->rs, mid+1, r, s, t);
    p->cnt = max(
        p->ls ? p->ls->cnt : 0,
        p->rs ? p->rs->cnt : 0
    );
}
int query(Node *p, int l, int r, int s, int t){
    if (!p) return 0;
    if (s <= l && r <= t) return p->cnt;
    int mid = l + r >> 1, ans = -2e9;
    if (s <= mid) ans = query(p->ls, l, mid, s, t);
    if (t > mid) ans = max(ans, query(p->rs, mid+1, r, s, t));
    return ans;
}
Node* merge(Node*&a, Node*&b, int l, int r){
    if (!a) return b;
    if (!b) return a;
    if (l==r){
        a->cnt += b->cnt;
        return a;
    }
    int mid = l + r >> 1;
    a->ls = merge(a->ls, b->ls, l, mid);
    a->rs = merge(a->rs, b->rs, mid+1, r);
    a->cnt = max(
        a->ls ? a->ls->cnt : 0,
        a->rs ? a->rs->cnt : 0
    );
    return a;
}
void dfs1(int u){
    for(auto v:e[u]){
        if (v == fa[u]) continue;
        dfs1(v);
        root[u] = merge(root[u], root[v], 1, 100000);
    }
}
int get(Node* p, int l, int r){
    if (!p) return 0;
    if (p->cnt <= 0) return 0;
    if (l==r) return l;
    int mid = l + r >> 1;
    int left_max = p->ls ? p->ls->cnt : 0;
    int right_max = p->rs ? p->rs->cnt : 0;
    if (left_max >= right_max) {
        return get(p->ls, l, mid);
    } else {
        return get(p->rs, mid + 1, r);
    }
}

int main(){
    cin>>n>>m;
    for(int i=1;i<n;i++){
        cin>>a>>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    dfs(1);
    initlca();
    while(m--){
        cin>>x>>y>>z;
        int lc = lca(x, y);
        add(root[x], 1, 100000, z, 1);
        add(root[y], 1, 100000, z, 1);
        add(root[lc], 1, 100000, z, -1);
        if (fa[lc]) add(root[fa[lc]], 1, 100000, z, -1);
    }
    dfs1(1);
    for(int i=1;i<=n;i++) cout << get(root[i], 1, 100000) << '\n';
}

回复

0 条回复,欢迎继续交流。

正在加载回复...