【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 雨天的尾巴 题目链接 题解: 因为一个点可能存放多种物品,直接开二维数组进行统计时间.空间复杂度都不能承受.因为每一个点所拥有的物品只与其子树中的点有关,所以可以考虑对每一个点来建立一 ...
随机推荐
- Hadoop国内主要发行版本
Hadoop主要版本 目前国内使用的不收费的Hadoop版本主要包括以下3个: Apache hadoop Cloudera的CDH Hortonworks版本(Hortonworks Data Pl ...
- MDK KEIL 机构体初始化 . 点 成员 初始化, C99
C99介绍,参考这里:C89,C99: C数组&结构体&联合体快速初始化 MDK 设置: 只需添加 ”--c99"参数即可,如图:
- spark1.0.2读取hbase(CDH0.96.1)上的数据
基本环境: 我是在win7环境下,spark1.0.2,HBase0.9.6.1 使用工具:IDEA14.1, scala 2.11.6, sbt.我现在是测试环境使用的是单节点 1.使用IDEA创建 ...
- 根据单个或多个字段对list对象去重
pojo 省略 在list 对象中,根据某一字段进行去重,重写Comparator /** * 去重 * * @param orderList * @return * @author ziggo * ...
- Python匹马行天下之运算符
什么事运算符? 本章节主要说明Python的运算符.举个简单的例子 4 +5 = 9 . 例子中,4 和 5 被称为操作数,"+" 称为运算符. Python语言支持以下类型的运算 ...
- 天道神诀---DHCP服务(上篇)
DHCP DHCP(Dynamic Host Configuration Protocol, 动态主机配置协议),被应用在局域网环境中,主要作用是集中的管理.分配IP地址,使网路环境中的主机动态的获得 ...
- Petrozavodsk Summer-2016. Warsaw U Contest, XVI Open Cup Onsite.
Petrozavodsk Summer-2016. Warsaw U Contest, XVI Open Cup Onsite. Problem A. Gambling Problem B. Colo ...
- LeetCode 31. Next Permutation【Medium】
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- Android开发 Button的开发记录
Button置顶层效果取消 android:stateListAnimator="@null" 在代码里执行点击 mButton.performClick(); //点击 mBut ...
- Apocalypse Someday
Apocalypse Someday 定义一个数是合法的,当且仅当中间出现至少一个连续的大于三个的6,求第x个合法的数,\(x\leq 50,000,000\) 解 首先,注意到求第几个,即想到试填法 ...