P4556 雨天的尾巴

题面

https://www.luogu.org/problem/P4556

题解

复制代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#define ri register int
#define Rb 100000

using namespace std;


int cnt=0,val[10000000],ch[10000000][2],mx[10000000],sum[10000000];
vector<int> to[100050];

int n,m,fa[100050],root[100050],f[100050][20],dep[100050];

void dfs(int x,int ff,int d) {
  f[x][0]=fa[x]=ff; dep[x]=d;
  for (ri i=1;i<=17;i++) f[x][i]=f[f[x][i-1]][i-1];
  for (ri i=to[x].size()-1;i>=0;i--) if (to[x][i]!=ff) {
    dfs(to[x][i],x,d+1);
  }
}

int Lca(int u,int v) {
  if (dep[u]<dep[v]) swap(u,v);
  for (ri i=17;i>=0;i--) if (dep[f[u][i]]>=dep[v]) u=f[u][i];
  if (u==v) return u;
  for (ri i=17;i>=0;i--) if (f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
  return fa[u];
}

void pushup(int x) {
  int lsum=0,rsum=0;
  if (ch[x][0]) lsum=sum[ch[x][0]];
  if (ch[x][1]) rsum=sum[ch[x][1]];
  if (lsum<rsum && rsum>0) {
    mx[x]=mx[ch[x][1]];
    sum[x]=rsum;
    return;
  }
  if (lsum>=rsum && lsum>0) {
    mx[x]=mx[ch[x][0]];
    sum[x]=lsum;
    return;
  }
  mx[x]=0;
}

void insert(int &x,int loc,int opt,int l,int r) {
  if (!x) x=++cnt;
  ri mid=(l+r)>>1;
  if (l==r) {
    sum[x]+=opt;
    mx[x]=l;
    return;
  }
  if (loc<=mid) insert(ch[x][0],loc,opt,l,mid); else insert(ch[x][1],loc,opt,mid+1,r);
  pushup(x);
}

void merge(int &u,int v,int l,int r) {
  if (!v) return;
  if (!u) {u=v;return;}
  if (l==r) {sum[u]+=sum[v]; mx[u]=l; return;}
  int mid=(l+r)>>1;
  merge(ch[u][0],ch[v][0],l,mid);
  merge(ch[u][1],ch[v][1],mid+1,r);
  pushup(u);
}

void treesum(int x) {
  for (ri i=to[x].size()-1;i>=0;i--) if (to[x][i]!=fa[x]) {
    treesum(to[x][i]);
    merge(root[x],root[to[x][i]],1,Rb);
  }
}

void calc(int x,int l,int r){
  if (!x) return;
  printf("%d %d %d %d %d\n",x,l,r,sum[x],mx[x]);
  calc(ch[x][0],l,(l+r)/2);
  calc(ch[x][1],(l+r)/2+1,r);
}

int main() {
  cnt=0;
  int u,v,x,y,z;
  scanf("%d %d",&n,&m);
  for (ri i=1;i<n;i++) {
    scanf("%d %d",&u,&v);
    to[u].push_back(v); to[v].push_back(u);
  }
  dfs(1,1,1);
  for (ri i=1;i<=n;i++) root[i]=i;
  cnt=n;
  for (ri i=1;i<=m;i++) {
    scanf("%d %d %d",&x,&y,&z);
    insert(root[x],z,1,1,Rb);
    insert(root[y],z,1,1,Rb);
    int lca=Lca(x,y);
    insert(root[lca],z,-1,1,Rb);
    if (lca!=1) insert(root[fa[lca]],z,-1,1,Rb);
  }
  treesum(1);
  for (ri i=1;i<=n;i++) {
    printf("%d\n",mx[root[i]]);
  }
}
复制代码

 

posted @   HellPix  阅读(143)  评论(0编辑  收藏  举报
编辑推荐:
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
· 程序员常用高效实用工具推荐,办公效率提升利器!
点击右上角即可分享
微信分享提示