【JZOJ3397】【luoguP4556】雨天的尾巴
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】雨天的尾巴的更多相关文章
- 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). 复杂度看起来不高, ...
- BZOJ_3307_雨天的尾巴_线段树合并+树上差分
BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...
- [Vani有约会]雨天的尾巴 线段树合并
[Vani有约会]雨天的尾巴 LG传送门 线段树合并入门好题. 先别急着上线段树合并,考虑一下这题的暴力.一看就是树上差分,对于每一个节点统计每种救济粮的数量,再一遍dfs把差分的结果统计成答案.如果 ...
- 【BZOJ 3307】 3307: 雨天的尾巴 (线段树+树链剖分)
3307: 雨天的尾巴 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 458 Solved: 210 Description N个点,形成一个树状结 ...
- 洛谷 P4556 [Vani有约会]雨天的尾巴 解题报告
P4556 [Vani有约会]雨天的尾巴 题目背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒 ...
- [luogu4556]雨天的尾巴
[luogu4556]雨天的尾巴 luogu 发现是一顿子修改然后再询问,那么把修改树上差分一下再线段树合并 但是... 如果你只有35分... https://www.luogu.org/discu ...
- 【BZOJ3307】雨天的尾巴 线段树合并
[BZOJ3307]雨天的尾巴 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多 ...
- Bzoj 3307 雨天的尾巴(线段树合并+树上差分)
C. 雨天的尾巴 题目描述 N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式 第 ...
- [bzoj3307]雨天的尾巴_线段树合并
雨天的尾巴 bzoj-3307 题目大意:N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. ...
- 洛谷P4556 雨天的尾巴(线段树合并)
洛谷P4556 雨天的尾巴 题目链接 题解: 因为一个点可能存放多种物品,直接开二维数组进行统计时间.空间复杂度都不能承受.因为每一个点所拥有的物品只与其子树中的点有关,所以可以考虑对每一个点来建立一 ...
随机推荐
- c# 将byte数组保存成图片
将byte数组保存成图片: 方式一:System.IO.File.WriteAllBytes(@"c:\test.jpg", bytes); 方式二:MemoryStream ms ...
- Mybatis笔记 – Po映射类型
一.输入映射类型 parameterType定义输入到sql中的映射类型,可以是 简单类型 .po类对象(可自动生成 或 手动定义). pojo包装对象(用于综合查询,UserCustom用户自定 ...
- ZK4字命令
zookeeper4字命令:两种方式,1.通过telnet链接服务器,执行stat.2.echo stat|nc xxx.xxx.xxx.xxx 2181效果是一样的conf:zk服务器运行时的基本信 ...
- 剑指offer——26反转链表
题目描述 输入一个链表,反转链表后,输出新链表的表头. 题解: 每次只反转一个节点,先记住cur->next, 然后pre->cur,即可; class Solution { pu ...
- PHP算法之增减字符串匹配
给定只含 "I"(增大)或 "D"(减小)的字符串 S ,令 N = S.length. 返回 [0, 1, ..., N] 的任意排列 A 使得对于所有 i ...
- 数据库的元数据抽取SQL
一.数据库驱动类.端口.默认用户名密码 数据库 驱动 端口 用户名 密码 MySQL com.mysql.jdbc.Driver 3306 root root DB2 com.ibm.db2.jcc. ...
- Android开发 AndroidStudio解决Error:moudle not specified
问题描述 在使用Android Studio 进行Builder APKs的时候,如果发现无法degub, 进行配置的时候 没有module可以进行指定 问题原因 项目未与Grade Files 文件 ...
- JAVA数据结构之红-黑树
本篇博客我会重点介绍对红-黑树的理解,重点介绍红-黑树的查找,这里我们将要讨论的算法称为自顶向下插入,也就是把沿着树向下查找插入点 Ⅰ.平衡树和非平衡树 平衡树和非平衡树:当插入一组数据关键字是按照升 ...
- C++ strcat_s
{ //如果用strcat() 连接时被连接的字符串是堆内存会 [损坏内存],使堆内存无法释放 建议用strcat_s() }
- day24 模块
Python之路,Day12 = Python基础12 模块 本质为py程序 分类: 内置模块 time time.time() ---> 当前时间的时间戳:浮点型 time.localtim ...