\(\mathscr{Description}\)

  Link.

  给定一棵以 \(1\) 为根的树,点 \(u\) 有非负点权 \(a_u\)。

  定义 \(u\) 的一次染色的代价为:路径 \(u\rightarrow 1\) 上染有的不为 \(u\) 的颜色种类,并把该路径上的所有结点颜色染为 \(u\)。

  定义一棵树的染色代价为:初始时所有结点无色,以任意顺序对结点进行染色操作,使得结点 \(u\) 恰好被操作 \(a_u\) 次,能得到的最大操作代价和。

  给出 \(m\) 次操作,每次给定 \(u,k\),\(k>0\),令 \(a_u\leftarrow a_u+k\)。每次修改后求出这棵树的染色代价。

  \(n,m\le4\times10^5\)。

\(\mathscr{Solution}\)

  惯用 trick:染色时的颜色冲突一定可以在 LCA 处不重不漏地统计。对于 \(u\),设其子树内的 \(a\) 之和为 \(s\),自己的权值以及孩子子树和的最大值为 \(x\),显然 \(u\) 处最多冲突

\[f(s,x)=\begin{cases}
s-1,&2x\le s\\
2(s-x),&2x>s
\end{cases}
\]

次,而 \(\sum_u f(s_u,x_u)\) 就是答案。

  奇妙的观察:修改的 \(k>0\),因此修改若在 \(u\) 的最大值子树内且 \(2x_u>s_u\),则一定不会导致 \(f(s_u,x_u)\) 改变。

  因此,可以 LCT 动态维护树形,\(u\) 与其原树孩子 \(v\) 是实边当且仅当 \(2s_u>s_v\)。注意这样的规定虽然导致我们完全不能 access,但是每遇到一条虚边,子树和 \(\times 2\),故任意结点到根的虚边数量恒不超过 \(\mathcal O(\log V)\)。修改时,转一转 splay,讨论一下每条虚边的取舍即可。

  虚边访问次数是 \(\mathcal O(q\log V)\),但 splay 内部是否能套用 LCT 的均摊证明其复杂度呢?或者说有什么巧妙的证明方法呢?求教 qwq。

\(\mathscr{Code}\)

/*+Rainybunny+*/

#include <bits/stdc++.h>

#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
#ifndef RYBY
# undef assert
# define assert(expr) // do nothing.
#endif typedef long long LL; inline char fgc() {
static char buf[1 << 17], *p = buf, *q = buf;
return p == q && (q = buf + fread(p = buf, 1, 1 << 17, stdin), p == q) ?
EOF : *p++;
} template <typename Tp = int>
inline Tp rint() {
Tp x = 0, s = fgc(), f = 1;
for (; s < '0' || '9' < s; s = fgc()) f = s == '-' ? -f : f;
for (; '0' <= s && s <= '9'; s = fgc()) x = x * 10 + (s ^ '0');
return x * f;
} template <typename Tp>
inline void wint(Tp x) {
if (x < 0) putchar('-'), x = -x;
if (9 < x) wint(x / 10);
putchar(x % 10 ^ '0');
} const int MAXN = 4e5;
int n, m, ecnt, head[MAXN + 5];
struct Edge { int to, nxt; } graph[MAXN * 2 + 5];
LL ans; inline void link(const int u, const int v) {
graph[++ecnt] = { v, head[u] }, head[u] = ecnt;
graph[++ecnt] = { u, head[v] }, head[v] = ecnt;
} struct LinkCutTree {
int fa[MAXN + 5], ch[MAXN + 5][2];
LL val[MAXN + 5], asum[MAXN + 5], vsum[MAXN + 5]; inline bool nroot(const int u) {
return ch[fa[u]][0] == u || ch[fa[u]][1] == u;
} inline void pushup(const int u) {
asum[u] = asum[ch[u][0]] + asum[ch[u][1]] + val[u] + vsum[u];
} inline LL contr(const int u) {
assert(!nroot(u));
LL s = asum[u] - asum[ch[u][0]];
if (ch[u][1]) {
// assert(asum[ch[u][1]] << 1 > s);
return s - asum[ch[u][1]] << 1;
}
if (val[u] << 1 > s) return s - val[u] << 1;
return s - 1;
} inline void init(const int u) { // specialized.
int mx = u; asum[u] = val[u];
for (int i = head[u], v; i; i = graph[i].nxt) {
if ((v = graph[i].to) != fa[u]) {
fa[v] = u, init(v), vsum[u] += asum[v];
if (asum[v] > asum[mx]) mx = v;
}
}
asum[u] += vsum[u];
if (mx != u && asum[mx] << 1 > asum[u]) {
ch[u][1] = mx, vsum[u] -= asum[mx];
}
ans += contr(u);
} inline void rotate(const int u) {
int v = fa[u], w = fa[v], k = ch[v][1] == u;
fa[u] = w; if (nroot(v)) ch[w][ch[w][1] == v] = u;
if ((ch[v][k] = ch[u][!k])) fa[ch[v][k]] = v;
pushup(ch[fa[v] = u][!k] = v), pushup(u);
} inline void splay(const int u) {
for (int v; nroot(u); rotate(u)) {
if (nroot(v = fa[u])) {
rotate(u ^ v ^ ch[v][0] ^ ch[fa[v]][0] ? u : v);
}
}
} inline void update(const int u, const int k) { // semi-access.
for (int v = u; v; v = fa[v]) {
splay(v), ans -= contr(v);
asum[v] += k, (u == v ? val[v] : vsum[v]) += k;
}
if (asum[ch[u][1]] << 1 <= asum[u] - asum[ch[u][0]]) {
vsum[u] += asum[ch[u][1]], ch[u][1] = 0;
}
ans += contr(u);
for (int v = u, w; (w = fa[v]); v = w) {
LL s = asum[w] - asum[ch[w][0]];
if (asum[ch[w][1]] << 1 <= s) {
vsum[w] += asum[ch[w][1]], ch[w][1] = 0;
}
if (asum[v] << 1 > s) {
vsum[w] -= asum[v], ch[w][1] = v;
}
ans += contr(w);
}
}
} lct; int main() {
n = rint(), m = rint();
rep (i, 1, n) lct.val[i] = rint();
rep (i, 2, n) link(rint(), rint()); lct.init(1);
wint(ans), putchar('\n');
for (int u, k; m--;) {
u = rint(), k = rint();
lct.update(u, k);
wint(ans), putchar('\n');
}
return 0;
}

Solution -「ZJOI 2018」「洛谷 P4338」历史的更多相关文章

  1. 洛谷P4338 [ZJOI2018]历史(LCT,树形DP,树链剖分)

    洛谷题目传送门 ZJOI的考场上最弱外省选手T2 10分成功滚粗...... 首先要想到30分的结论 说实话Day1前几天刚刚刚掉了SDOI2017的树点涂色,考场上也想到了这一点 想到了又有什么用? ...

  2. 「区间DP」「洛谷P1043」数字游戏

    「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...

  3. Solution -「JSOI 2019」「洛谷 P5334」节日庆典

    \(\mathscr{Description}\)   Link.   给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的).   \(|S|\le3\time ...

  4. Solution -「洛谷 P4372」Out of Sorts P

    \(\mathcal{Description}\)   OurOJ & 洛谷 P4372(几乎一致)   设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...

  5. Solution -「POI 2010」「洛谷 P3511」MOS-Bridges

    \(\mathcal{Description}\)   Link.(洛谷上这翻译真的一言难尽呐.   给定一个 \(n\) 个点 \(m\) 条边的无向图,一条边 \((u,v,a,b)\) 表示从 ...

  6. Solution -「APIO 2016」「洛谷 P3643」划艇

    \(\mathcal{Description}\)   Link & 双倍经验.   给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...

  7. 「洛谷4197」「BZOJ3545」peak【线段树合并】

    题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...

  8. 「洛谷3338」「ZJOI2014」力【FFT】

    题目链接 [BZOJ] [洛谷] 题解 首先我们需要对这个式子进行化简,否则对着这么大一坨东西只能暴力... \[F_i=\sum_{j<i} \frac{q_iq_j}{(i-j)^2}-\s ...

  9. 「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】

    题目链接 [洛谷] 题解 很明显是要用线段树合并的. 对于当前的每一个连通块都建立一个权值线段树. 权值线段树处理操作中的\(k\)大的问题. 如果需要合并,那么就线段树暴力合并,时间复杂度是\(nl ...

  10. 「洛谷3870」「TJOI2009」开关【线段树】

    题目链接 [洛谷] 题解 来做一下水题来掩饰ZJOI2019考炸的心情QwQ. 很明显可以线段树. 维护两个值,\(Lazy\)懒标记表示当前区间是否需要翻转,\(s\)表示区间还有多少灯是亮着的. ...

随机推荐

  1. freeswitch的话单处理

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. 如果对cdr话单要求不高,可以直接使用fs的原始话单文件,使用脚本做一些简单的统计. 环境 CentOS 7.9 freeswitc ...

  2. 如何使用git上传代码github仓库

    本文对于Windows系统上git的安装及基本使用方法进行简单介绍,并介绍如何使用git将仓库中的项目上传至个人的Github中去. 1.打开git 打开你想上传文件的位置,然后选择git bash ...

  3. linux下时间时区详解

    首先我们要明白,"时间"和"时区"是两个东西. 时间是指从某个时间点开始到另一个时间点经过的"长度",是"纵向"距离,一 ...

  4. 使用wxpython开发跨平台桌面应用,常用窗体布局BoxSizer,FlexGridSizer,GridBagSizer的介绍处理

    我们在开发桌面应用的时候,不管是之前C#开发Winform的时候,还是现在使用wxpython来开发跨平台应用的时候,都需要了解布局的处理,wxpython的常用布局Sizer类,包括BoxSizer ...

  5. 2024/10/3 CSP-S模拟赛20241003

    A 恶心恶心恶心,赛时写了一个二分+线段树的复杂度错了,当时yzh和lyz就一会骗我一会说实话的,搞得很懵,自己水平也是菜,那线段树分析复杂度怎么不把递归次数乘上呢?大傻逼grz 思路其实还挺好的. ...

  6. 如何看待:以色列在真主党订购的5000台寻呼机中放了TNT

    日常生活等关键物品的生产必须要有国内完全掌握,美国.日本.以色列等国惯用的这种暗杀方法.如果不能在本国国内做到自主可控的产品生产,那么无疑是把自己的脑袋交给敌人来保护,随时都有丢命的可能. 同时,这也 ...

  7. IIC通信协议详解 & PCF8591应用(Verilog实现)

    该文章结合PCF8591 8-bit AD/DA 模数/数模转换器来详细介绍IIC通信协议,尽量做到条理清晰,通俗易懂.该文图片均从PCF8591手册中截取,一定程度上引导读者学习阅读data she ...

  8. 基于Java+SpringBoot+Mysql实现的快递柜寄取快递系统功能实现三

    一.前言介绍: 1.1 项目摘要 随着电子商务的迅猛发展和城市化进程的加快,快递业务量呈现出爆炸式增长的趋势.传统的快递寄取方式,如人工配送和定点领取,已经无法满足现代社会的快速.便捷需求.这些问题不 ...

  9. 【python】利用tqdm实现git下载时的进度条效果

    注意1:这里是在python3环境下使用的git,安装要使用 pip install Gitpython 来安装在python环境下的git 注意2:这个方法可适用于 windows 环境和 Linu ...

  10. Sickos1.1 详细靶机思路 实操笔记

    Sickos1.1 详细靶机思路 实操笔记 免责声明 本博客提供的所有信息仅供学习和研究目的,旨在提高读者的网络安全意识和技术能力.请在合法合规的前提下使用本文中提供的任何技术.方法或工具.如果您选择 ...