Solution -「UOJ #418」三角形
\(\mathscr{Description}\)
Link.
给定一棵含有 \(n\) 个结点的有根树, 点 \(u\) 有正权 \(w_u\). 每次操作可以:
- 在 \(u\) 上放 \(w_u\) 枚石子. 必须满足 \(u\) 的儿子全部都放了对应数量的石子.
- 回收结点 \(u\) 上的所有石子.
对于每个点, 求为了在这个点上放上石子, 至少需要准备多少枚石子.
\(n\le2\times10^5\).
\(\mathscr{Solution}\)
限制条件为 "儿子选完父亲选", 我们知道 "父亲选完儿子选" 有经典的贪心结论, 所以可以反过来考虑决策顺序.
对于点 \(u\) 单独的操作, 可以描述为二元组 \((w_u-\sum w_v,w)\), 表示本次操作需要准备 \(w\) 枚石子, 操作完成后石子的变化量为 \(w_u-\sum w_v\). 对于二元组 \((a,b),(c,d)\) 依次合并, 显然有 \((a,b)+(c,d)=(a+c,\max\{b,a+d\})\). 二元组操作顺序只需要依据操作后需准备石子的数量关系, 取数量最小的一种即可. 这是一个用于贪心的偏序关系.
正如前文所说, 如果是 "父亲选完选儿子", 可以反复找出全局最优解与父亲合并. 而这里, 我们可把整个决策倒过来. 那么 \((a,b)\rightarrow (-a,b-a)\), 在按照结论即可合并. 据此模拟出全局最有的操作策略, 在这一顺序上建立线段树, 线段树合并维护每棵子树的策略二元组之和就能求出答案. 复杂度 \(\mathcal O(n\log n)\).
\(\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)
typedef long long LL;
typedef std::pair<LL, LL> PLL;
#define fi first
#define se second
template <typename Tp>
inline void chkmin(Tp& u, const Tp& v) { v < u && (u = v, 0); }
template <typename Tp>
inline void chkmax(Tp& u, const Tp& v) { u < v && (u = v, 0); }
template <typename Tp>
inline Tp imin(const Tp& u, const Tp& v) { return u < v ? u : v; }
template <typename Tp>
inline Tp imax(const Tp& u, const Tp& v) { return u < v ? v : u; }
const int MAXN = 2e5;
int n, fa[MAXN + 5], val[MAXN + 5], ord[MAXN + 5], root[MAXN + 5];
std::vector<int> adj[MAXN + 5], fol[MAXN + 5];
bool vis[MAXN + 5];
LL sub[MAXN + 5], ans[MAXN + 5];
PLL wgt[MAXN + 5];
struct DSU {
int fa[MAXN + 5];
inline void init() {
rep (i, 1, n) fa[i] = i;
}
inline int find(const int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
inline void unite(const int x, const int y) {
fa[find(x)] = find(y);
}
} dsu;
inline PLL operator + (const PLL& u, const PLL& v) {
return { u.fi + v.fi, imax(u.se, u.fi + v.se) };
}
struct CmpFn {
inline bool operator () (const int u, const int v) const {
LL d = (wgt[u] + wgt[v]).se - (wgt[v] + wgt[u]).se;
if (d) return d < 0;
if (wgt[u] != wgt[v]) return wgt[u] < wgt[v];
return u < v;
}
};
std::set<int, CmpFn> heap;
inline void append(const int u) {
assert(!vis[u]);
ord[u] = ++ord[0], vis[u] = true;
for (int v: fol[u]) append(v);
}
struct SegmentTree {
static const int MAXND = 4e6;
int node, ch[MAXND][2]; PLL uni[MAXND];
inline void pushup(const int u) {
uni[u] = uni[ch[u][0]] + uni[ch[u][1]];
}
inline void merge(int& u, const int v) {
if (!u || !v) return void(u |= v);
merge(ch[u][0], ch[v][0]), merge(ch[u][1], ch[v][1]);
pushup(u);
}
inline void insert(int& u, const int l, const int r,
const int x, const PLL& w) {
if (!u) u = ++node;
if (l == r) return void(uni[u] = w);
int mid = l + r >> 1;
if (x <= mid) insert(ch[u][0], l, mid, x, w);
else insert(ch[u][1], mid + 1, r, x, w);
pushup(u);
}
} sgt;
inline void solve(const int u) {
for (int v: adj[u]) solve(v), sgt.merge(root[u], root[v]);
sgt.insert(root[u], 1, n, ord[u], { sub[u] - val[u], sub[u] });
ans[u] = (PLL(val[u], val[u]) + sgt.uni[root[u]]).se;
}
int main() {
scanf("%*d %d", &n);
rep (i, 2, n) scanf("%d", &fa[i]), adj[fa[i]].push_back(i);
rep (i, 1, n) scanf("%d", &val[i]), sub[fa[i]] += val[i];
dsu.init();
rep (i, 1, n) wgt[i] = { sub[i] - val[i], sub[i] }, heap.insert(i);
rep (i, 1, n) {
int u = *heap.begin();
// fprintf(stderr, "%d\n", u);
heap.erase(heap.begin());
if (u == 1 || vis[fa[u]]) append(u);
else {
int v = dsu.find(fa[u]);
heap.erase(v);
wgt[v] = wgt[v] + wgt[u], dsu.unite(u, v);
heap.insert(v), fol[v].push_back(u);
}
}
solve(1);
rep (i, 1, n) printf("%lld%c", ans[i], i < n ? ' ' : '\n');
return 0;
}
Solution -「UOJ #418」三角形的更多相关文章
- Solution -「UOJ #46」玄学
\(\mathcal{Description}\) Link. 给定序列 \(\{a_n\}\) 和 \(q\) 次操作,操作内容如下: 给出 \(l,r,k,b\),声明一个修改方案,表示 ...
- Solution -「UOJ #87」mx 的仙人掌
\(\mathcal{Description}\) Link. 给出含 \(n\) 个结点 \(m\) 条边的仙人掌图.\(q\) 次询问,每次询问给出一个点集 \(S\),求 \(S\) 内 ...
- Solution -「UOJ #450」复读机
\(\mathcal{Description}\) Link. 求从 \(m\) 种颜色,每种颜色无限多的小球里选 \(n\) 个构成排列,使得每种颜色出现次数为 \(d\) 的倍数的排列方案 ...
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution -「UNR #5」「UOJ #671」诡异操作
\(\mathcal{Desciprtion}\) Link. 给定序列 \(\{a_n\}\),支持 \(q\) 次操作: 给定 \(l,r,v\),\(\forall i\in[l,r], ...
- Solution -「JOISC 2020」「UOJ #509」迷路的猫
\(\mathcal{Decription}\) Link. 这是一道通信题. 给定一个 \(n\) 个点 \(m\) 条边的连通无向图与两个限制 \(A,B\). 程序 Anthon ...
- Solution -「UR #21」「UOJ #632」挑战最大团
\(\mathcal{Description}\) Link. 对于简单无向图 \(G=(V,E)\),定义它是"优美"的,当且仅当 \[\forall\{a,b,c,d\ ...
- Solution -「UR #2」「UOJ #32」跳蚤公路
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的带权有向图,每条边还有属性 \(s\in\{-1,0,1\}\).对于每个 \(u ...
- Solution -「CTS 2019」「洛谷 P5404」氪金手游
\(\mathcal{Description}\) Link. 有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...
- Solution -「BZOJ 3812」主旋律
\(\mathcal{Description}\) Link. 给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...
随机推荐
- awk 处理 Git 提交信息生成 Release Note
发布软件时通常都会写 Release Note,但每次从头手打也有点累,可以考虑从 Git 的提交历史中自动生成. Git 提交信息一般是三段式结构,段落之间使用空行隔开: <subject&g ...
- Docker Compose容器编排--项目五
一.Docker Compose概念 Docker Compose (可简称Compose)是一个定义与运行复杂应用程序的 Docker 工具,是 Docker 官方 编排(Orchestration ...
- Java面试题及答案整理汇总(2024最新版)
前言 辞退了老板,准备找下家,又要开始面试了,不得不准备准备八股文,还是很有必要针对性的刷一些题,很多朋友的实战能力很强,但是理论比较薄弱,要多准备准备理论知识,攻克面试官.这是我在全网寻找稍微比较完 ...
- ABC372 (D,E)
ABC372 (D,E) D 一道比较简单的二分查找题目. 观察到每个数能成为 \(j\) 的条件是独立的,因此想到统计每个数能成为它前面哪些数的 \(j\). 对于每个\(ed\), 二分 \(1 ...
- C++ STL 容器简介
1.总述 C++ STL(Standard Template Library)是 C++ 标准库的一部分,包括了许多数据结构的实现,提供了许多好用的轮子,同时,其设计思想也非常值得学习.其中,容器是 ...
- PHP之常见问题
汇总在PHP开发中遇到的一些问题 1.post提交参数缺失 场景: 在前端页面发起一个post提交的时候,查看payload中的数据是正常的, 但是在接收的时候,发现只有部分数据,算了一下,包含的数据 ...
- 使用阿里的ARTHAS跟踪方法耗时
使用命令跟踪一个方法的耗时 在arthas 命令行下输入命令 trace 类全路径 监控的方法 trace com.redxun.bpm.core.service.BpmInstServiceImpl ...
- 《前端运维》二、Nginx--2请求处理流程及核心模块
前一篇内容,我们学习了nginx的一些基本概念.安装和目录的作用.这篇文章我们来学习一些更加深入的内容. 一.Nginx请求处理流程 我们先来看张图吧: 我们看上图,首先客户端请求到Nginx服务器, ...
- MeteoInfo-Java解析与绘图教程(十)_JAVA绘制雷达PPI图
天气雷达的基本要素有很多,特别是双偏振雷达更多,但业务场景经常使用的一般为基本反射率,基本速度这两种要素 接下来我们以基本反射率为例,其他的要素也是一样的,一通百通 首先我们做基本反射率的图需要确定做 ...
- 备份场景全覆盖!腾讯云备份一体机 B2000给您全方位保护
TStor 是腾讯云面向混合云场景打造的存储一体机产品系列.继年初发布对象存储一体机之后,该产品系列再添新成员:TStor B2000,是面向混合云备份场景的一体机产品. 根据权威咨询机构 IDC 和 ...