【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. 【CF1029A】Many Equal Substrings(模拟)

    题意:给定一个长度为n的串s,要求构造一个长度最小的使s出现了k次的串,可以重叠 n<=50,k<=50 思路:计算一下前后缀相同长度 #include<cstdio> #in ...

  2. JavaScript基础深入之----参数传递的分析与总结

    JS的数值类型是分为两类:基本数据类型和引用数据类型. 基本类型占据的内存栈空间,引用类型被保存在堆空间.引用类型赋值的变量也是被保存在栈空间的,它的作用类似于电视遥控器,负责操作堆空间内指向的对象. ...

  3. 算法 & 数据结构——任意多边形填充

    需求 . 在计算机中,选区是一个很常见的功能,例如windows按住鼠标左键拖动划出矩形选区,Photshop通过钢笔工具任意形状选区.选区本身不过是通过线段闭合的一个几何形状,但是如何填充这个选区, ...

  4. spring boot--日志、开发和生产环境切换、自定义配置(环境变量)

    Spring Boot日志常用配置: # 日志输出的地址:Spring Boot默认并没有进行文件输出,只在控制台中进行了打印 logging.file=/home/zhou # 日志级别 debug ...

  5. LeetCode OJ-- Simplify Path **

    https://oj.leetcode.com/problems/simplify-path/ 对linux路径的规范化,属于字符串处理的题目.细节很多. #include <iostream& ...

  6. Codeforces 599E Sandy and Nuts(状压DP)

    题目链接 Sandy and Nuts 题意大概就是给出限制条件求出在该限制条件下树的种数. #include <bits/stdc++.h> using namespace std; # ...

  7. Java获取指定时间(转)

    说明:从LocalDate的API上看,主要用于快速获取当前年月日,而DateFormatter也基本上伴随着使用.如果是操作Date对象的,主要是用于时间戳等,伴随着使用的是SimpleDateFo ...

  8. cookie读取设置name

    cookie就是k-v形式,可以理解为一个hashmap cookie就是k-v形式,可以理解为一个hashmap cookie就是k-v形式,可以理解为一个hashmap 建立一个无生命周期的coo ...

  9. arcgis andriod 加载影像

    MapView mMapView;......String rasterPath = Environment.getExternalStorageDirectory().getPath() + &qu ...

  10. 现代数字信号处理——AR模型

    1. AR模型概念观       AR模型是一种线性预测,即已知N个数据,可由模型推出第N点前面或后面的数据(设推出P点),所以其本质类似于插值,其目的都是为了增加有效数据,只是AR模型是由N点递推, ...