传送门

Solution

线段树合并的入门题

lca可以在dfs的时候离线求(用并查集)

更新的点有每条链的两个端点,它们的lca和dad[lca]

为了节省空间,lca和dad[lca]的更新可以先存储下来,等搜完该点后再做

##Code

#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
#define MN 100005
#define N 100000
int n,m,z[MN],ans[MN];
struct ques{int b,nex;}q[MN<<1];
int qhr[MN],cnt=1;
struct edge{int to,nex;}e[MN<<1];
int hr[MN],en;
inline void qins(int f,int t)
{
q[++cnt]=(ques){t,qhr[f]};qhr[f]=cnt;
if(f==t) ++cnt;
else q[++cnt]=(ques){f,qhr[t]},qhr[t]=cnt;
}
inline void ins(int f,int t)
{
e[++en]=(edge){t,hr[f]};hr[f]=en;
e[++en]=(edge){f,hr[t]};hr[t]=en;
}
int fa[MN],dad[MN];
bool vis[MN];
inline int getf(int x){return fa[x]==x?x:fa[x]=getf(fa[x]);}
#define mid ((l+r)>>1)
int ls[MN*40],rs[MN*40],rt[MN],t[MN*40],seg;
void merge(int &x,int y,int l,int r)
{
if(!x||!y){x=x+y;return;}
if(l==r){t[x]+=t[y];return;}
merge(ls[x],ls[y],l,mid);
merge(rs[x],rs[y],mid+1,r);
t[x]=max(t[ls[x]],t[rs[x]]);
}
int query(int x,int l,int r)
{
if(!x||!t[x]) return 0;
if(l==r) return l;
return t[rs[x]]>t[ls[x]]?query(rs[x],mid+1,r):query(ls[x],l,mid);
}
void update(int &x,int l,int r,int p,int v)
{
if(!x) x=++seg;
if(l==r){t[x]+=v;return;}
if(p>mid) update(rs[x],mid+1,r,p,v);
if(p<=mid) update(ls[x],l,mid,p,v);
t[x]=max(t[ls[x]],t[rs[x]]);
}
std::map<int,int> mar[MN];
void dfs(int x,int f)
{
register int i;
fa[x]=x;dad[x]=f;
for(i=hr[x];i;i=e[i].nex)if(f^e[i].to)
{
dfs(e[i].to,x);
fa[e[i].to]=x;
merge(rt[x],rt[e[i].to],1,N);
}
vis[x]=true;
for(i=qhr[x];i;i=q[i].nex)if(vis[q[i].b]==true)
{
int lca=getf(q[i].b);
mar[lca][z[i>>1]]--;mar[dad[lca]][z[i>>1]]--;
}
std::map<int,int>::iterator it;
for(it=mar[x].begin();it!=mar[x].end();++it) update(rt[x],1,N,it->first,it->second);
ans[x]=query(rt[x],1,N);
}
int main()
{
n=read(),m=read();
register int i,j,k;
for(i=1;i<n;++i) ins(read(),read());
for(i=1;i<=m;++i)
{
j=read(),k=read(),z[i]=read();
qins(j,k),update(rt[j],1,N,z[i],1),update(rt[k],1,N,z[i],1);
}
dfs(1,0);
for(i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

[洛谷 P4556] 雨天的尾巴的更多相关文章

  1. 洛谷P4556 雨天的尾巴(线段树合并)

    洛谷P4556 雨天的尾巴 题目链接 题解: 因为一个点可能存放多种物品,直接开二维数组进行统计时间.空间复杂度都不能承受.因为每一个点所拥有的物品只与其子树中的点有关,所以可以考虑对每一个点来建立一 ...

  2. [洛谷P4556] 雨天的尾巴

    这道题可以用线段树合并做,网上的题解基本上都是线段树合并的. 但是为什么我就偏偏要用dsu on tree...... 题目传送门 dsu on tree的方法类似[CF1009F] Dominant ...

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

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

  4. 洛谷 P4556 [Vani有约会]雨天的尾巴 解题报告

    P4556 [Vani有约会]雨天的尾巴 题目背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒 ...

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

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

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

    传送门 要求维护每个点上出现次数最多的颜色. 对于每次修改,我们用树上差分的思想,然后线段树合并统计答案就行了. 注意颜色很大需要离散化. 代码: #include<bits/stdc++.h& ...

  7. 【洛谷P4556】 雨天的尾巴

    题面 题解 线段树合并 我们看到这道题目首先可以想到树上差分,然后\(dfs\)合并 发现题目让我们求的东西很好用线段树维护 于是可以想到线段树合并 全世界只有我写指针版动态开点线段树(大雾 如果你要 ...

  8. [洛谷P4556][BZOJ3307]雨天的尾巴-T3订正

    线段树合并+树上差分 题目链接(···) 「简单」「一般」——其实「一般」也只多一个离散化 考试时想法看>这里< 总思路:先存所有的操作,离散化,然后用树上差分解决修改,用权值线段树维护每 ...

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

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

随机推荐

  1. YII 的SPA 写法

    'use strict'; var findToolbar = function () { return document.querySelector('#yii-debug-toolbar'); } ...

  2. Java 日期时间与unix时间戳之间转换

    日期时间  <-->  时间戳 java.time 包提供的新的日期和时间API LocalDateTime: 本地日期时间类 ZoneId: 时区类 ZonedDateTime: 带时区 ...

  3. C++中头文件与源文件的作用详解

    一.C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件―― .cpp 文件和 .h 文件.其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码:而 .h 文件则被称作 ...

  4. C# 利用特性(Attribute)实现通用实体类数据合法校验

    用过asp.net mvc 的都应该知道,在实体类上添加一些特性,可以实现后端实体的数据校验,这里简单实现一下 实现原理:利用反射获取实体的每一个属性,并通过属性获取属性上标注的特性,调用特性的Val ...

  5. hadoop2.8 集群 1 (伪分布式搭建)

    简介: 关于完整分布式请参考: hadoop2.8 ha 集群搭建   [七台机器的集群] Hadoop:(hadoop2.8) Hadoop是一个由Apache基金会所开发的分布式系统基础架构.用户 ...

  6. Python学习日记(三) 学习使用dict

    数据按类型可划分为: 不可变数据类型(可哈希):元祖.string.int.bool 可变数据类型(不可哈希):dict.list 集合本身是可变数据类型,元素是不可变数据类型 字典中的key必须是不 ...

  7. Docker -compose install Harbor

    Docker-compose Harbor install Docker install Yum install docker-compose 首先安装 yum configuation 管理工具 [ ...

  8. Keil、uVision、RealView、MDK、Keil C51之间的区别比较

    我们要区别的概念:KEIL UVision,KEIL MDK,KEIL For ARM,RealView MDK,KEIL C51,KEIL C166,KEIL C251 从接触MCS-51单片机开始 ...

  9. PXE+Kickstart无人值守安装---CentOS7.

    1.安装一台CentOS7.x桌面版本系统的服务器,关闭selinux和防火墙: 2.在服务器安装pxe+kickstart无人值守需要的软件 : yum install dhcp tftp-serv ...

  10. GCC 编译流程简介

    GCC-GCC编译流程 序言 对于大多数程序员而言,大家都知道gcc是什么,但是如果不接触到linux平台下的开发,鲜有人真正了解gcc的编译流程,因为windows+IDE的开发模式简直是一条龙全套 ...