题目链接

题目大意:给定一颗含有$n$个结点的树,每次选择两个结点$x$和$y$,对从$x$到$y$的路径上发放一带$z$类型的物品。问完成所有操作后每个结点发放最多的时哪种物品。

普通的树链剖分貌似也可以做这道题,可以记录一个$c$数组用来记录结点中每种物品的个数,然后暴力乱搞。空间可能会炸。

这时候我们需要一种新算法:树上差分

关于树上差分,有需要的同学可以去看大佬的博客,我这里说一下思想。

对于序列的差分,我们都知道,假设让序列中$i-j$的数都加上$z$,那么直接让差分数组$b[i]+=z$,$b[j]-=z$即可。放到一颗树中(其实这里变成了子树和),让路径上$s-t$的结点都加上$k$,我们只需在$s,t$加上$k$,在$lca(s,t),fa[lca(s,t)]$减去$k$即可。实际上树上差分的实现形式多种多样,我们可以根据题目需要来作改动。

对于此题,我们不妨用$\log n$的时间把路径$x,y$拆分成$[a_1,b_1],[a_2,b_2],\cdots ,[a_k,b_k]$这样多个区间的形式,每次在$a_i$处加上$z$,在$b_i+1$处减去$z$。写起来是这样的:

inline void chai(int x,int y,int c)
{
while(top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
Add(dfn[top[x]],c);Add(dfn[x]+,-c);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
Add(dfn[x],c);Add(dfn[y]+,-c);
}

个数可以用线段树维护。其实正解应该是动态开点+线段树合并之类的高级算法,但是我不会QAQ。所以只写了较为普通的线段树维护。时间复杂度$n\log n$。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=;
int n,m;
int size[maxn],son[maxn],dep[maxn],fa[maxn];
int dfn[maxn],cnt,w[maxn],top[maxn],ans[maxn];//w[dfn[x]]=x; ans[w[i]]=sum;
int head[maxn*],jishu;
int Head[maxn*],Jishu;
struct node
{
int next,to,val;
}edge[maxn*],Edge[maxn*];//Edge chai
struct tre
{
int maxx,pos;
}tree[maxn*];
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void add(int from,int to)
{
edge[++jishu].next=head[from];
edge[jishu].to=to;
head[from]=jishu;
}
inline void Add(int from,int val)
{
Edge[++Jishu].next=Head[from];
Edge[Jishu].val=val;
Head[from]=Jishu;
}
inline void dfs_son(int now,int f,int deep)
{
dep[now]=deep;
fa[now]=f;
size[now]=;
int maxson=-;
for (int i=head[now];i;i=edge[i].next)
{
int to=edge[i].to;
if (to==f) continue;
dfs_son(to,now,deep+);
size[now]+=size[to];
if (maxson<size[to]) maxson=size[to],son[now]=to;
}
}
inline void dfs(int now,int tp)
{
dfn[now]=++cnt;
top[now]=tp;
w[cnt]=now;
if (son[now]) dfs(son[now],tp);
for (int i=head[now];i;i=edge[i].next)
{
int to=edge[i].to;
if (dfn[to]) continue;
dfs(to,to);
}
}
inline void pushup(int index)
{
if (tree[index*].maxx>=tree[index*+].maxx) tree[index].maxx=tree[index*].maxx,tree[index].pos=tree[index*].pos;
else tree[index].maxx=tree[index*+].maxx,tree[index].pos=tree[index*+].pos;
}
inline void build(int index,int l,int r)
{
if (l==r){tree[index].maxx=;tree[index].pos=l;return;}
int mid=(l+r)>>;
build(index*,l,mid);
build(index*+,mid+,r);
pushup(index);
}
inline void update(int index,int l,int r,int pos,int k)
{
if (l==r){tree[index].maxx+=k;return;}
int mid=(l+r)>>;
if (pos<=mid) update(index*,l,mid,pos,k);
if (pos>mid) update(index*+,mid+,r,pos,k);
pushup(index);
}
inline void chai(int x,int y,int c)
{
while(top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
Add(dfn[top[x]],c);Add(dfn[x]+,-c);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
Add(dfn[x],c);Add(dfn[y]+,-c);
}
signed main()
{
n=read(),m=read();
for (int i=;i<n;i++)
{
int x=read(),y=read();
add(x,y);add(y,x);
}
dfs_son(,,);
dfs(,);
for (int i=;i<=m;i++)
{
int x=read(),y=read(),z=read();
chai(x,y,z);
}
build(,,);
//for (int i=1;i<=n;i++) cout<<w[i]<<endl;
for (int i=;i<=n;i++)
{
for (int j=Head[i];j;j=Edge[j].next)
{
if (Edge[j].val>) update(,,,Edge[j].val,);
else update(,,,-Edge[j].val,-);
}
ans[w[i]]=tree[].maxx?tree[].pos:;
}
//cout<<Jishu;
for (int i=;i<=n;i++) printf("%lld\n",ans[i]);
return ;
}

【BZOJ3307】雨天的尾巴 题解(树链剖分+树上差分)的更多相关文章

  1. BZOJ 3631 松鼠的新家 - 树链剖分 / 树上差分

    传送门 分析: 树链剖分:x->y,将x到y的路径加一,并将x端点的答案-1,最后统计答案. 树上差分:x->y,x+1,y+1,lca-1,fa[lca]-1,并将x打上标记,最后统计前 ...

  2. 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 703  Solved: 461[Submit][Status] ...

  3. bzoj 3307: 雨天的尾巴【树剖lca+树上差分+线段树合并】

    这居然是我第一次写线段树合并--所以我居然在合并的时候加点结果WAWAWAMLEMLEMLE--!ro的时候居然直接指到la就行-- 树上差分,每个点建一棵动态开点线段树,然后统计答案的时候合并即可 ...

  4. 【CodeChef EDGEST】Edges in Spanning Trees(树链剖分+树上启发式合并)

    点此看题面 大致题意: 给你两棵\(n\)个点的树,对于第一棵树中的每条边\(e_1\),求存在多少条第二棵树中的边\(e_2\),使得第一棵树删掉\(e_1\)加上\(e_2\).第二棵树删掉\(e ...

  5. P3384 【模板】树链剖分 题解&&树链剖分详解

    题外话: 一道至今为止做题时间最长的题: begin at 8.30A.M 然后求助_yjk dalao后 最后一次搞取模: awsl. 正解开始: 题目链接. 树链剖分,指的是将一棵树通过两次遍历后 ...

  6. 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点

    题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...

  7. 洛谷P2486 [SDOI2011]染色 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2486 首先这是一道树链剖分+线段树的题. 线段树部分和 codedecision P1112 区间连续段 一模一样,所以我们 ...

  8. 洛谷P2146 [NOI2015]软件包管理器 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2146 本题涉及算法: 树链剖分: 线段树(区间更新及求和,涉及懒惰标记) 然后对于每次 install x ,需要将 x 到 ...

  9. 洛谷P3178 [HAOI2015]树上操作 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P3178 这道题目是一道树链剖分的模板题. 但是在解决这道问题的同事刷新了我的两个认识: 第一个认识是:树链剖分不光可以处理链, ...

随机推荐

  1. 大致掌握django的功能

    目录 静态文件配置 request对象方法初识 pycharm链接数据库(mysql) django链接数据库(mysql) django orm 字段的增删查改 数据的增删查改 数据的查,改,删 d ...

  2. Fetch.AI 首席技术官Toby Simpson参与AMA活动

    感谢7月11日在YouTube上参与 Fetch.AI AMA的所有人.我们收到了大量的问题,遗憾的是我们没有时间回答其中的多数问题.如果你错过了现场AMA,你可以在下面观看全部内容: 在本文中,我们 ...

  3. 关于小白一天摆弄Axure产品原型的心得

    因为项目所需,被迫快速设计产品原型,制作app使用视频,这里简单分享一些一个小白第一次触碰产品原型设计的一些心得: 原型设计工具的选用 我这里针对的是贫穷学生党,分享的是自己尝试的几款.有钱大佬自行绕 ...

  4. CRM【第三篇】: crm业务

    1. 项目背景 crm系统是某某教育公司正在使用的项目,系统主要为 销售部.运营部.教质部门提供管理平台,随着公司规模的扩展,对公司员工的业务信息量化以及信息化建设越来越重要. crm系统为不同角色的 ...

  5. Python数据可视化:画饼状图、折线图、圈图

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. from math import pi import matplotlib ...

  6. proxy是什么

    普通的因特网访问是一个典型的客户机与服务器结构:用户利用计算机上的客户端程序,如浏览器发出请求,远端WWW服务器程序响应请求并提供相应的数据.而Proxy处于客户机与服务器之间,对于服务器来说,Pro ...

  7. OSCP Learning Notes - Enumeration(3)

    SMB Enumeration 1. Set the smb configurations. locate smb.conf vim /etc/samba/smb.conf Insert the gl ...

  8. Docker 基础知识 - 使用绑定挂载(bind mounts)管理应用程序数据

    绑定挂载(bind mounts)在 Docker 的早期就已经出现了.与卷相比,绑定挂载的功能有限.当您使用绑定挂载时,主机上的文件或目录将挂载到容器中.文件或目录由其在主机上的完整或相对路径引用. ...

  9. 学完自动化测试,用小技能做了点兼职刷弹幕,小赚10W

    大家好,今天又给大家带来了Python爬虫的分享,继续来研究一下虎牙平台的爬虫. 起因 我冒出有一个很有趣的想法,就是,我们可以使用selenium来完成虎牙自动化登录,并且自动给主播发送弹幕功能的程 ...

  10. NAS存储的定义和优势介绍

    今天来跟大家分享下私有云的一种应用形式NAS.作为常见的个人和家庭私有云存储方案,NAS就像我们随身的数据存储中心,它有低损耗高效率的特点,那么NAS如何搭建,家用NAS存储有哪些优势呢,一起来看看吧 ...