社区讨论
Only AC #1,2,4 求调
P4556【模板】线段树合并 / [Vani 有约会] 雨天的尾巴参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mhj2zy7o
- 此快照首次捕获于
- 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 条回复,欢迎继续交流。
正在加载回复...