原题链接

每个点开一个权值线段树,然后用树上差分的方法修改,最后自底向上暴力线段树合并即可。

不过空间较大,会\(MLE\),写个内存池就可以了。

#include<cstdio>
#include<cmath>
using namespace std;
const int N = 1e5 + 10;
const int M = 6e6 + 10;
struct dd {
int x, y, z;
};
dd a[N];
int fi[N], di[N << 1], ne[N << 1], ro[N], S[M], CO[M], L[M], R[M], de[N], f[N][18], an[N], sta[M], l, ma, gn, SEG, tp;
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline void add(int x, int y)
{
di[++l] = y;
ne[l] = fi[x];
fi[x] = l;
}
inline void sw(int &x, int &y)
{
int z = x;
x = y;
y = z;
}
inline int maxn(int x, int y){ return x > y ? x : y; }
void dfs(int x)
{
int i, y;
for (i = 1; i <= gn; i++)
f[x][i] = f[f[x][i - 1]][i - 1];
for (i = fi[x]; i; i = ne[i])
if (!de[y = di[i]])
{
de[y] = de[x] + 1;
f[y][0] = x;
dfs(y);
}
}
int lca(int x, int y)
{
int i;
if (de[x] > de[y])
sw(x, y);
for (i = gn; ~i; i--)
if (de[f[y][i]] >= de[x])
y = f[y][i];
if (!(x ^ y))
return x;
for (i = gn; ~i; i--)
if (f[x][i] ^ f[y][i])
{
x = f[x][i];
y = f[y][i];
}
return f[x][0];
}
void pp(int r)
{
int lx = L[r], rx = R[r];
if (S[lx] < S[rx])
{
S[r] = S[rx];
CO[r] = CO[rx];
}
else
{
S[r] = S[lx];
CO[r] = CO[lx];
}
}
inline void rec(int x){ sta[++tp] = x; }
inline int NEW(){ return tp ? sta[tp--] : ++SEG; }
void mdf(int &r, int x, int y, int k, int v)
{
if (!r)
r = ++SEG;
if (!(x ^ y))
{
S[r] += v;
S[r] > 0 ? CO[r] = x : CO[r] = 0;
return;
}
int mid = (x + y) >> 1;
k <= mid ? mdf(L[r], x, mid, k, v) : mdf(R[r], mid + 1, y, k, v);
pp(r);
}
int merge(int x, int y, int r_1, int r_2)
{
if (!r_1)
return r_2;
if (!r_2)
return r_1;
int r = NEW();
if (!(x ^ y))
{
S[r] = S[r_1] + S[r_2];
S[r] > 0 ? CO[r] = x : CO[r] = 0;
return r;
}
int mid = (x + y) >> 1;
L[r] = merge(x, mid, L[r_1], L[r_2]);
R[r] = merge(mid + 1, y, R[r_1], R[r_2]);
pp(r);
rec(r_1);
rec(r_2);
return r;
}
void UPD(int x)
{
int i, y;
for (i = fi[x]; i; i = ne[i])
if ((y = di[i]) ^ f[x][0])
{
UPD(y);
ro[x] = merge(1, ma, ro[x], ro[y]);
}
an[x] = CO[ro[x]];
}
int main()
{
int i, n, m, x, y, LCA;
n = re();
m = re();
gn = log2(n);
for (i = 1; i < n; i++)
{
x = re();
y = re();
add(x, y);
add(y, x);
}
de[1] = 1;
dfs(1);
for (i = 1; i <= m; i++)
{
a[i].x = re();
a[i].y = re();
a[i].z = re();
ma = maxn(ma, a[i].z);
}
for (i = 1; i <= m; i++)
{
LCA = lca(a[i].x, a[i].y);
mdf(ro[a[i].x], 1, ma, a[i].z, 1);
mdf(ro[a[i].y], 1, ma, a[i].z, 1);
mdf(ro[LCA], 1, ma, a[i].z, -1);
if (LCA ^ 1)
mdf(ro[f[LCA][0]], 1, ma, a[i].z, -1);
}
UPD(1);
for (i = 1; i <= n; i++)
printf("%d\n", an[i]);
return 0;
}

洛谷4556 [Vani有约会]雨天的尾巴的更多相关文章

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

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

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

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

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

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

  4. 洛咕 P4556 [Vani有约会]雨天的尾巴

    终于把考试题清完了...又复活了... 树上差分,合并用线段树合并,但是空间会炸. 某大佬:lca和fa[lca]减得时候一定已经存在这个节点了,所以放进vector里,合并完之后减掉就好了... 玄 ...

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

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

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

    P4556 [Vani有约会]雨天的尾巴 每个操作拆成4个进行树上差分,动态开点线段树维护每个点的操作. 离线处理完向上合并就好了 luogu倍增lca被卡了5分.....于是用rmq维护.... 常 ...

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

    P4556 [Vani有约会]雨天的尾巴 题意: 首先村落里的一共有n座房屋,并形成一个树状结构.然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋 ...

  8. 「Luogu4556」Vani有约会-雨天的尾巴

    「Luogu4556」Vani有约会-雨天的尾巴 传送门 很显然可以考虑树上差分+桶,每次更新一条链就是把这条链上的点在桶对应位置打上 \(1\) 的标记, 最后对每个点取桶中非零值的位置作为答案即可 ...

  9. [题解] P4556 [Vani有约会]雨天的尾巴

    [题解] P4556 [Vani有约会]雨天的尾巴 ·题目大意 给定一棵树,有m次修改操作,每次修改 \(( x\) \(y\) \(z )\) 表示 \((x,y)\) 之间的路径上数值 \(z\) ...

随机推荐

  1. flex 布局压缩问题

    在 flex 布局中,当有一个元素宽度过长时,另一个元素宽度会被压缩, 如下图: 解决办法:在不想被压缩的元素上加上样式 flex-shrink: 0; 效果图:

  2. 如何增加黑客通过ssh入侵的难度--保护ssh的三把锁

    源文档:https://blog.csdn.net/cnbird2008/article/details/6130696 简介 如果需要远程访问计算机并启用了 Secure Shell (SSH) 连 ...

  3. mysqlbinlog基于时间点恢复

    基于时间点恢复 /data/mysq/mysqlbin.000026 #mysqlbinlog文件,恢复如下内容: 注意:按照时间点恢复时,可能同一个时间点有其他的操作,要结合上下文的时间选取~ # ...

  4. Linux(CentOS-7) 下载 解压 安装 redis 操作的一些基本命令

    使用xshell 连接到虚拟机,并且创建 一个redis目录:创建文件命令:mkdir 文件名ls:查看当前文件里面的所有文件 使用xftp 将下载的linux版本 reids上传动新建的redis目 ...

  5. Altium Designer9.4局域网内冲突的问题

    Altium Designer破解 1.安装Altium Designer原程序.2.运行AD9KeyGen,点击“打开模板”,加载ad9.ini,如想修改注册名,只需修改:TransactorNam ...

  6. JS高级-异步

    单线程 只有一个线程,同一时间只能做一件事 原因:避免DOM渲染的冲突 浏览器需要渲染DOM JS可以修改DOM结果 JS执行的时候,浏览器DOM渲染会暂停 两段JS也不能同时执行(修改DOM就冲突) ...

  7. leetcode17

    回溯法,深度优先遍历(DFS) public class Solution { int[] x; int N; string DIGITS; Dictionary<char, List<s ...

  8. Digital Twin的8种解读!

    国际8大主流厂商对digital twin的理解,很有必要来一次汇总! 据IDC预测,2017年世界上将有40%的大型生产商都会应用虚拟仿真技术来为他们的生产过程进行建模,Digital Twin可以 ...

  9. Sql Server数据库之事务,视图,索引

    一.事务的定义 事务是一种机制,包含一组操作指令,并将所有的命令作为一个整体一起向系统提交或撤销操作请求(要么都执行,要么都不执行) 二.事务的分类 显式事务:用Begin TRANSCATION开始 ...

  10. MFC笔记10

    1. CDC MemDC1; MemDC1.SetBkMode(OPAQUE); 背景模式,VC6下面有三种:/* Background Modes */#define TRANSPARENT 1// ...