description

深绘里一直很讨厌雨天。

灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切。

虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连

根拔起,以及田地里的粮食被弄得一片狼藉。

无奈的深绘里和村民们只好等待救济粮来维生。

不过救济粮的发放方式很特别。

首先村落里的一共有n 座房屋,并形成一个树状结构。然后救济粮分m 次发放,每次选择

两个房屋(x,y),然后对于x 到y 的路径上(含x 和y) 每座房子里发放一袋z 类型的救济粮。

然后深绘里想知道,当所有的救济粮发放完毕后,每座房子里存放的最多的是哪种救济粮。


analysis

  • 树上倍增\(+\)树上差分\(+\)线段树合并

  • 可以在\(x,y\)打上\(1\)标记,\(LCA,fa[LCA]\)打上\(-1\)标记

  • 这样合并子树信息时到\(LCA\)刚好只算一次,到\(fa[LCA]\)就没算

  • 找\(LCA\)当然可以用倍增

  • 线段树合并大概就是把两棵线段树维护同一区间的节点的左右儿子信息合并一下

  • 如果一边没有某个儿子就把另一个节点的那个儿子接上,复杂度是\(O(\log_2n)\)的

  • 由于节点非常多所以动态开点,所有操作后从叶子节点到根一层层合并线段树就好

  • 感觉这题知识点很多,不能偷懒,要好好学…


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAX 200000
#define MAXN 200005
#define MAXM 6000005
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=last[a];i;i=next[i]) using namespace std; ll last[MAXN<<1],next[MAXN<<1],tov[MAXN<<1];
ll depth[MAXN],ans[MAXN],root[MAXN];
ll anc[MAXN][19],lson[MAXM],rson[MAXM];
ll n,m,tot;
pair<ll,ll>tr[MAXM]; struct node
{
ll x,y,z;
}f[MAXN]; inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline ll max(ll x,ll y){return x>y?x:y;}
inline void swap(ll &x,ll &y){ll z=x;x=y,y=z;}
inline void link(ll x,ll y){next[++tot]=last[x],last[x]=tot,tov[tot]=y;}
inline void dfs(ll x){rep(i,x)if (tov[i]!=anc[x][0])depth[tov[i]]=depth[x]+1,anc[tov[i]][0]=x,dfs(tov[i]);}
inline ll lca(ll x,ll y)
{
if (depth[x]<depth[y])swap(x,y);
fd(i,18,0)if (depth[anc[x][i]]>=depth[y])x=anc[x][i];if (x==y)return x;
fd(i,18,0)if (anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i];return anc[x][0];
}
inline void insert(ll &t,ll l,ll r,ll x,ll y)
{
if (!t)t=++tot;
if (l==r){tr[t]=make_pair(tr[t].first+y,-x);return;}
ll mid=(l+r)>>1;
if (x<=mid)insert(lson[t],l,mid,x,y);
else insert(rson[t],mid+1,r,x,y);
tr[t]=max(tr[lson[t]],tr[rson[t]]);
}
inline ll merge(ll x,ll y,ll l,ll r)
{
if (!x)return y;if (!y)return x;
ll mid=(l+r)>>1;
if (l==r){tr[x].first+=tr[y].first;return x;}
lson[x]=merge(lson[x],lson[y],l,mid),rson[x]=merge(rson[x],rson[y],mid+1,r),
tr[x]=max(tr[lson[x]],tr[rson[x]]);return x;
}
inline void dfs_merge(ll x)
{
rep(i,x)if (tov[i]!=anc[x][0])dfs_merge(tov[i]),root[x]=merge(root[x],root[tov[i]],1,MAX);
ans[x]=-tr[root[x]].second;
}
int main()
{
freopen("T3.in","r",stdin);
n=read(),m=read();
fo(i,1,n-1)
{
ll x=read(),y=read();
link(x,y),link(y,x);
}
depth[1]=1,dfs(1),tot=0;
fo(j,1,18)fo(i,1,n)anc[i][j]=anc[anc[i][j-1]][j-1];
while (m--)
{
ll x=read(),y=read(),z=read(),tmp=lca(x,y);
insert(root[x],1,MAX,z,1),insert(root[y],1,MAX,z,1),
insert(root[tmp],1,MAX,z,-1),insert(root[anc[tmp][0]],1,MAX,z,-1);
}
dfs_merge(1);
fo(i,1,n)printf("%lld\n",ans[i]);
return 0;
}

【JZOJ3397】【luoguP4556】雨天的尾巴的更多相关文章

  1. BZOJ 3307: 雨天的尾巴( LCA + 线段树合并 )

    路径(x, y) +z : u处+z, v处+z, lca(u,v)处-z, fa(lca)处-z, 然后dfs一遍, 用线段树合并. O(M log M + M log N). 复杂度看起来不高, ...

  2. BZOJ_3307_雨天的尾巴_线段树合并+树上差分

    BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...

  3. [Vani有约会]雨天的尾巴 线段树合并

    [Vani有约会]雨天的尾巴 LG传送门 线段树合并入门好题. 先别急着上线段树合并,考虑一下这题的暴力.一看就是树上差分,对于每一个节点统计每种救济粮的数量,再一遍dfs把差分的结果统计成答案.如果 ...

  4. 【BZOJ 3307】 3307: 雨天的尾巴 (线段树+树链剖分)

    3307: 雨天的尾巴 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 458  Solved: 210 Description N个点,形成一个树状结 ...

  5. 洛谷 P4556 [Vani有约会]雨天的尾巴 解题报告

    P4556 [Vani有约会]雨天的尾巴 题目背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒 ...

  6. [luogu4556]雨天的尾巴

    [luogu4556]雨天的尾巴 luogu 发现是一顿子修改然后再询问,那么把修改树上差分一下再线段树合并 但是... 如果你只有35分... https://www.luogu.org/discu ...

  7. 【BZOJ3307】雨天的尾巴 线段树合并

    [BZOJ3307]雨天的尾巴 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多 ...

  8. Bzoj 3307 雨天的尾巴(线段树合并+树上差分)

    C. 雨天的尾巴 题目描述 N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式 第 ...

  9. [bzoj3307]雨天的尾巴_线段树合并

    雨天的尾巴 bzoj-3307 题目大意:N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. ...

  10. 洛谷P4556 雨天的尾巴(线段树合并)

    洛谷P4556 雨天的尾巴 题目链接 题解: 因为一个点可能存放多种物品,直接开二维数组进行统计时间.空间复杂度都不能承受.因为每一个点所拥有的物品只与其子树中的点有关,所以可以考虑对每一个点来建立一 ...

随机推荐

  1. AdaBoost笔记之原理

    转自:https://www.cnblogs.com/ScorpioLu/p/8295990.html 一.Boosting提升算法 AdaBoost是典型的Boosting算法,属于Boosting ...

  2. 9.3.2 The force and release procedural statements

    Frm: IEEE Std 1364™-2001, IEEE Standard Verilog® Hardware Description Language Another form of proce ...

  3. Spark 调优之数据倾斜

    什么是数据倾斜? Spark 的计算抽象如下 数据倾斜指的是:并行处理的数据集中,某一部分(如 Spark 或 Kafka 的一个 Partition)的数据显著多于其它部分,从而使得该部分的处理速度 ...

  4. org.apache.hadoop.hbase.PleaseHoldException: Master is initializing

    电脑换了重新装了下系统,在本机ubuntu 的环境下搭建hadoopCDH4.5 伪分布式.进入Hbase shell,在创建表的时候出现异常如下: ERROR: org.apache.hadoop. ...

  5. eclipse导入别人项目配置tomcat和jdk

    1.file--import--General--Existing Projiect into Workspace-- 2.导入项目成功后,项目会有错误,需重新进行tomcat及jdk的配置 项目名右 ...

  6. 6-Python操作MySQL-增(insert)-删(delete)-改(update)-查(select)

    增删改 from pymysql import * def main(): # 创建Connection连接 conn = connect(host='localhost',port=3306,dat ...

  7. Jmeter---参数化之用户参数

    总结: 参数化几次就要设置几个线程,执行的时候,是按顺序执行,下面的请求也会跟着请求

  8. Immutable 想破坏它也没办法

    上一章讲的是线程互斥的synchronized实现,这样做会影响性能,如何才能做到既不影响性能又能达到线程安全的目的呢,就是使用状态绝不会改变的类,Java中的应用就是String类. public ...

  9. .net中的泛型全面解析

    从2.0起我们一直就在谈论泛型,那么什么是泛型,泛型有什么好处,与泛型相关的概念又该怎么使用,比如泛型方法,泛型委托.这一篇我会全面的介绍泛型. 那么首先我们必须搞清楚什么是泛型,泛型其实也是一种类型 ...

  10. 用js判断是否是微信浏览器

      //判断是否是微信浏览器的函数 function isWeiXin(){ //window.navigator.userAgent属性包含了浏览器类型.版本.操作系统类型.浏览器引擎类型等信息,这 ...