题目传送门


题目描述

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


输入格式

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


输出格式

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


样例

样例输入:

20 50
8 6
10 6
18 6
20 10
7 20
2 18
19 8
1 6
14 20
16 10
13 19
3 14
17 18
11 19
4 11
15 14
5 18
9 10
12 15
11 14 87
12 1 87
14 3 84
17 2 36
6 5 93
17 6 87
10 14 93
5 16 78
6 15 93
15 5 16
11 8 50
17 19 50
5 4 87
15 20 78
1 17 50
20 13 87
7 15 22
16 11 94
19 8 87
18 3 93
13 13 87
2 1 87
2 6 22
5 20 84
10 12 93
18 12 87
16 10 93
8 17 93
14 7 36
7 4 22
5 9 87
13 10 16
20 11 50
9 16 84
10 17 16
19 6 87
12 2 36
20 9 94
9 2 84
14 1 94
5 5 94
8 17 16
12 8 36
20 17 78
12 18 50
16 8 94
2 19 36
10 18 36
14 19 50
4 12 50

(有点长……)

样例输出:

87
36
84
22
87
87
22
50
84
87
50
36
87
93
36
94
16
87
50
50


数据范围与提示

1≤N,M≤100000
1≤a,b,x,y≤N
1≤z≤109


题解

看到这道题我首先想到了这道题:BZOJ3631

对于上面这道题,如果你还没有思路的话可以看一下这篇博客:[BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)

然后,我就立马想到了先求出LCA然后进行树上差分,但是这两道题的区别在于,这道题的物品种类不止一个,而且数还不小,显然不能单纯的用树上差分来解决。

于是考虑用权值线段树维护,先将物品种类排序,然后看利用树上差分更新权值线段树,之后递归合并统计答案即可。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec//存边
{
int nxt;
int to;
}e[200000];
struct qwq//存操作
{
int x;
int y;
int z;
}question[100001];
int head[100001],cnt;
int fa[100001][20];
int root[100001],trfal[10000001],trsum[10000001],ls[10000001],rs[10000001],sum,tot;
int dfsv[100001];
int depth[100001];
int que[100001];
bool cmp(qwq a,qwq b){return a.z<b.z;}//按物品排序问题
void add(int x,int y)//建边
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
head[x]=cnt;
}
void dfs(int x)//dfs预处理父亲和深度
{
dfsv[++dfsv[0]]=x;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=fa[x][0])
{
fa[e[i].to][0]=x;
depth[e[i].to]=depth[x]+1;
for(int j=1;j<=18;j++)
fa[e[i].to][j]=fa[fa[e[i].to][j-1]][j-1];
dfs(e[i].to);
}
}
int LCA(int x,int y)//倍增求LCA
{
if(depth[x]<depth[y])swap(x,y);
for(int i=18;i>=0;i--)
if(depth[fa[x][i]]>=depth[y])x=fa[x][i];
if(x==y)return x;
for(int i=18;i>=0;i--)
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
return fa[x][0];
}
void pushup(int x)
{
trfal[x]=max(trfal[ls[x]],trfal[rs[x]]);//维护的权值
trsum[x]=(trfal[ls[x]]>=trfal[rs[x]])?trsum[ls[x]]:trsum[rs[x]];//哪种物品
}
void insert(int &x,int k,int fl,int l,int r)
{
if(!x)x=++tot;
if(l==r)
{
trfal[x]+=fl;
trsum[x]=que[l];
return;
}
int mid=(l+r)>>1;
if(k<=mid)insert(ls[x],k,fl,l,mid);
else insert(rs[x],k,fl,mid+1,r);
pushup(x);
}
void ask(int &x,int fl,int l,int r)
{
if(!fl)return;
if(!x)
{
x=fl;
return;
}
if(l==r)
{
trfal[x]+=trfal[fl];
return;
}
int mid=(l+r)>>1;
ask(ls[x],ls[fl],l,mid);
ask(rs[x],rs[fl],mid+1,r);
pushup(x);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)root[i]=i;
tot=n;
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
depth[1]=1;
dfs(1);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&question[i].x,&question[i].y,&question[i].z);
sort(question+1,question+m+1,cmp);
for(int i=1;i<=m;i++)
{
int lca=LCA(question[i].x,question[i].y);
if(question[i].z>question[i-1].z)que[++sum]=question[i].z;
insert(root[question[i].x],sum,1,1,m);//树上差分操作
insert(root[question[i].y],sum,1,1,m);
insert(root[lca],sum,-1,1,m);
if(lca!=1)insert(root[fa[lca][0]],sum,-1,1,m);
}
for(int i=n;i>1;i--)
ask(root[fa[dfsv[i]][0]],root[dfsv[i]],1,m);
for(int i=1;i<=n;i++)
printf("%d\n",trsum[root[i]]);
return 0;
}

rp++

[BZOJ3307]:雨天的尾巴(LCA+树上差分+权值线段树)的更多相关文章

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

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

  2. 【bzoj3307】雨天的尾巴 权值线段树合并

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

  3. HDU-6704 K-th occurrence (后缀自动机father树上倍增建权值线段树合并)

    layout: post title: HDU-6704 K-th occurrence (后缀自动机father树上倍增建权值线段树合并) author: "luowentaoaa&quo ...

  4. 【bzoj4719】[Noip2016]天天爱跑步 权值线段树合并

    题目描述 给出一棵n个点的树,以及m次操作,每次操作从起点向终点以每秒一条边的速度移动(初始时刻为0),最后对于每个点询问有多少次操作在经过该点的时刻为某值. 输入 第一行有两个整数N和M .其中N代 ...

  5. BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

    题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...

  6. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  7. BZOJ_2161_布娃娃_权值线段树

    BZOJ_2161_布娃娃_权值线段树 Description 小时候的雨荨非常听话,是父母眼中的好孩子.在学校是老师的左右手,同学的好榜样.后来她成为艾利斯顿第二 代考神,这和小时候培养的良好素质是 ...

  8. cf1073G Yet Another LCP Problem (SA+权值线段树)

    反正先求一遍sa 然后这个问题可以稍微转化一下 默认比较A.B数组中元素的大小都是比较它们rank的大小,毕竟两个位置的LCP就是它们rank的rmq 然后每次只要求B[j]>=A[i]的LCP ...

  9. BZOJ3110[Zjoi2013]K大数查询——权值线段树套线段树

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...

随机推荐

  1. win10+PHP 安装redis

    1.给php环境安装redis扩展 2.给电脑安装redis环境 一.为php安装redis服务 使用 phpinfo() 函数查看php对应的版本 二.去下面的两个网站下载对应版本的压缩包并解压(注 ...

  2. OPENGL4_变换

    几种变换的几何意义说明 http://blog.csdn.net/onafioo/article/details/22094247 变换的执行顺序问题 正常顺序 1 视图(观察)变换 2 模型变换 3 ...

  3. Metabolic Signatures of Cystic Fibrosis Identified in Dried Blood Spots For Newborn Screening Without Carrier Identification (文献分享一组-孔楠楠)

    题目:Metabolic Signatures of Cystic Fibrosis Identified in Dried Blood Spots For Newborn Screening Wit ...

  4. 自然语言处理(五)——实现机器翻译Seq2Seq完整经过

    参考书 <TensorFlow:实战Google深度学习框架>(第2版) 我只能说这本书太烂了,看完这本书中关于自然语言处理的内容,代码全部敲了一遍,感觉学的很绝望,代码也运行不了. 具体 ...

  5. echarts散点图重叠

    今天做echarts图标,使用了散点图.很快实现,发现数据不对,应该是3个的企业,页面只显示了2个,查了半天才发现原来是有两个重叠了.想办法解决了,在网上费劲九牛二虎只力终于找到了解决的方法,下面来解 ...

  6. 集成Activiti工作流的J2EE快速开发框架

    框架简介 enos款快速开发模块化脚手架,实现功能有系统模块:菜单管理.用户管理.角色管理,系统监控:系统日志.接口api.sql监控. 系统功能 系统管理:菜单管理.用户管理.角色管理 统一查询 p ...

  7. mysql_innodb引擎

    innodb概括 1.Innodb是一种事务性存储引擎 2.完全支持事务的ACID特性 3.实现事务特性的原理: 使用Redo Log和Undo Log,Undo Log用于帮助未提交事务进行回滚,R ...

  8. 【bzoj1726】Roadblocks

    1726: [Usaco2006 Nov]Roadblocks第二短路 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1578  Solved: 795[ ...

  9. ZOJ How Many Nines 模拟 | 打表

    How Many Nines Time Limit: 1 Second      Memory Limit: 65536 KB If we represent a date in the format ...

  10. js中对象与函数的关系

    首先什么是对象?根据W3C上面的解释JS中所有事物都是对象,对象是拥有属性和方法的数据,由此可以看出基本值类型不是对象(number.string.Boolean.Undefined),剩下的引用类型 ...