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]]); } }
分类:
5.0 数据结构
, 5.3 数据结构——树状数组和线段树
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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)
· 程序员常用高效实用工具推荐,办公效率提升利器!