【BZOJ3307】雨天的尾巴

Description

N个点,形成一个树状结构。有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成所有发放后,每个点存放最多的是哪种物品。

Input

第一行数字N,M
接下来N-1行,每行两个数字a,b,表示a与b间有一条边
再接下来M行,每行三个数字x,y,z.如题

Output

输出有N行
每i行的数字表示第i个点存放最多的物品是哪一种,如果有多种物品的数量一样,输出编号最小的。如果某个点没有物品则输出0

题解:看到题直接的想法就是树套树,但是由于可以离线,我们可以直接差分。

具体地,我们对于每个点都维护一棵权值线段树,然后将标记差分,最后将每个节点的线段树与父亲节点的线段树合并即可。

建议:在一开始的时候就为每个点创建一个rt节点。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=100010;
int inf=1000000000;
int n,m,cnt,tot;
int to[maxn<<1],next[maxn<<1],head[maxn],fa[19][maxn],dep[maxn],rt[maxn],p[maxn],ref[maxn];
int v[maxn*50],s[maxn*50],ls[maxn*50],rs[maxn*50];
struct node
{
int a,b,c;
}q[maxn];
bool cmp(node a,node b)
{
return a.c<b.c;
}
int rd()
{
int ret=0; char gc=getchar();
while(gc<'0'||gc>'9') gc=getchar();
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret;
}
void add(int a,int b)
{
to[++cnt]=b,next[cnt]=head[a],head[a]=cnt;
}
void dfs(int x)
{
p[++p[0]]=x;
for(int i=head[x];i;i=next[i])
if(to[i]!=fa[0][x]) fa[0][to[i]]=x,dep[to[i]]=dep[x]+1,dfs(to[i]);
}
int lca(int a,int b)
{
if(dep[a]<dep[b]) swap(a,b);
for(int i=18;i>=0;i--) if(dep[fa[i][a]]>=dep[b]) a=fa[i][a];
if(a==b) return a;
for(int i=18;i>=0;i--) if(fa[i][a]!=fa[i][b]) a=fa[i][a],b=fa[i][b];
return fa[0][a];
}
void pushup(int x)
{
v[x]=max(v[ls[x]],v[rs[x]]);
s[x]=(v[ls[x]]>=v[rs[x]])?s[ls[x]]:s[rs[x]];
}
void insert(int &x,int a,int b,int l,int r)
{
if(!x) x=++tot;
if(l==r)
{
v[x]+=b,s[x]=ref[l];
return ;
}
int mid=l+r>>1;
if(a<=mid) insert(ls[x],a,b,l,mid);
else insert(rs[x],a,b,mid+1,r);
pushup(x);
}
void merge(int &a,int b,int l,int r)
{
if(!b) return ;
if(!a)
{
a=b;
return ;
}
if(l==r)
{
v[a]+=v[b];
return ;
}
int mid=l+r>>1;
merge(ls[a],ls[b],l,mid),merge(rs[a],rs[b],mid+1,r);
pushup(a);
}
int main()
{
int i,j,a,b,c,d;
n=rd(),m=rd();
for(i=1;i<=n;i++) rt[i]=++tot;
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
dep[1]=1,dfs(1);
for(j=1;(1<<j)<=n;j++) for(i=1;i<=n;i++) fa[j][i]=fa[j-1][fa[j-1][i]];
for(i=1;i<=m;i++) q[i].a=rd(),q[i].b=rd(),q[i].c=rd();
sort(q+1,q+m+1,cmp);
for(d=0,i=1;i<=m;i++)
{
a=q[i].a,b=q[i].b,c=lca(a,b);
if(q[i].c>q[i-1].c) ref[++d]=q[i].c;
insert(rt[a],d,1,0,m),insert(rt[b],d,1,0,m),insert(rt[c],d,-1,0,m);
if(c!=1) insert(rt[fa[0][c]],d,-1,0,m);
}
for(i=n;i>1;i--) merge(rt[fa[0][p[i]]],rt[p[i]],0,m);
for(i=1;i<=n;i++) printf("%d\n",s[rt[i]]);
return 0;
}

【BZOJ3307】雨天的尾巴 线段树合并的更多相关文章

  1. BZOJ3307雨天的尾巴——线段树合并

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

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

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

  3. P4556 雨天的尾巴 线段树合并

    使用线段树合并,每个节点维护一棵权值线段树,下标为救济粮种类,区间维护数量最多的救济粮编号(下标).所以每个节点答案即为\(tre[rot[x]]\). 然后运用树上点的差分思想,对于分发路径\(u, ...

  4. bzoj 3307: 雨天的尾巴 线段树合并

    题目大意: N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.问完成所有发放后,每个点存放最多的是哪种物品. 题解: 首先我们为每一个节 ...

  5. [BZOJ3307] 雨天的尾巴-----------------线段树进阶

    虽然是个板子,但用到了差分思想. Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最 ...

  6. 洛谷P4556 [Vani有约会]雨天的尾巴(线段树合并)

    题目背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连根拔起,以及田地 ...

  7. 洛谷P4556 雨天的尾巴 线段树

    正解:线段树合并 解题报告: 传送门! 考虑对树上的每个节点开一棵权值线段树,动态开点,记录一个max(num,id)(这儿的id,define了一下,,,指的是从小到大排QAQ 然后修改操作可以考虑 ...

  8. [BZOJ3307] 雨天的尾巴(树上差分+线段树合并)

    [BZOJ3307] 雨天的尾巴(树上差分+线段树合并) 题面 给出一棵N个点的树,M次操作在链上加上某一种类别的物品,完成所有操作后,要求询问每个点上最多物品的类型. N, M≤100000 分析 ...

  9. 雨天的尾巴(bzoj3307)(线段树合并+树上差分)

    \(N\)个点,形成一个树状结构.有\(M\)次发放,每次选择两个点\(x,y\) 对于\(x\)到\(y\)的路径上(含\(x,y\))每个点发一袋\(Z\)类型的物品.完成 所有发放后,每个点存放 ...

随机推荐

  1. HibernateException: No Hibernate Session bound to thread

    解决No Hibernate Session bound to thread 背景交代 在使用this.getHibernateTemplate().getSessionFactory().getCu ...

  2. 百度图表echars插件使用案例

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...

  3. 模仿手机qq空间头部向上滚动颜色加深

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 标准C程序设计七---70

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  5. 眉目传情之匠心独运的kfifo【转】

    转自:http://blog.csdn.net/chen19870707/article/details/39899743 权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 一 ...

  6. hdu 5437(优先队列模拟)

    Alisha’s Party Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  7. spring boot教程(一):入门篇(非原创,总结笔记性质)

    一,什么是spring boot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发 ...

  8. Java中ArrayList的初始容量和容量分配

    1.实例化ArrayList时默认不输入大小是10个,并且如果增加到11个时不会报错,会自动扩容. 2.获取指定索引的值时就必须保证ArrayList有这么多个. 3.推荐在new ArrayList ...

  9. JavaWeb过滤器.监听器.拦截器-?原理&区别

    过滤器可以简单理解为“取你所想取”,忽视掉那些你不想要的东西:拦截器可以简单理解为“拒你所想拒”,关心你想要拒绝掉哪些东西,比如一个BBS论坛上拦截掉敏感词汇. 1.拦截器是基于java的反射机制,过 ...

  10. SQL SERVER 内存

    http://www.cnblogs.com/CareySon/archive/2012/08/16/HowSQLServerManageMemory.html