首页 > 其他分享 >CF932F Escape Through Leaf【DP,李超线段树】

CF932F Escape Through Leaf【DP,李超线段树】

时间:2024-02-27 20:25:07浏览次数:192  
标签:le Leaf int LL 李超 节点 Through calc id

有一颗 \(n\) 个节点的树,根节点为 \(1\)。每个节点有两个权值,第 \(i\) 个节点的权值为 \(a_i,b_i\)。

你可以从一个节点跳到它的子树内任意一个节点上。从节点 \(x\) 跳到节点 \(y\) 一次的花费为 \(a_x\times b_y\)。跳跃多次走过一条路径的总费用为每次跳跃的费用之和。求每个节点到达树的任意叶子节点的费用的最小值。

\(2 \le n \le 10^5\),\(-10^5 \le a_i,b_i \le 10^5\)。


比较板一个题。首先显然有 \(\mathcal{O}(n^2)\) DP:设 \(f_u\) 为从 \(u\) 出发的答案,则 \(f_u = \min\limits_{v \in T_u} \{ f_v + a_u \times b_v \}\),其中 \(T_u\) 表示 \(u\) 的子树。然后这个式子一看就是一次函数的形式,直接上李超树。合并子树的时候李超树合并就行了。注意一下李超树合并是 单 \(\log\) 的。

这题定义域有负数,可以平移一下。但其实也不是必要的。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair <int, int> pi;
#define fi first
#define se second
#define all(x) x.begin(), x.end()
constexpr int N = 2e5 + 5, M = 1e5 + 5;
constexpr LL inf = 1e18;
bool Mbe;
int n, root[N], tot;
vector <int> e[N];
LL ans[N], a[N], b[N];
int lc[N << 5], rc[N << 5], p[N << 5];
struct line {
	LL k, b;
} t[N];
inline LL calc(int i, LL x) { return t[i].k * x + t[i].b; }
#define m ((l + r) >> 1)
void insert(int &x, int l, int r, int id) {
	if (!x) return x = ++tot, p[x] = id, void();
	if (calc(p[x], m) > calc(id, m)) swap(p[x], id);
	if (calc(p[x], l) <= calc(id, l) &&
		calc(p[x], r) <= calc(id, r)) return;
	if (calc(p[x], l) > calc(id, l)) insert(lc[x], l, m, id);
	else insert(rc[x], m + 1, r, id);
}
LL qry(int x, int l, int r, LL pos) {
	if (!x) return inf;
	LL res = calc(p[x], pos);
	if (pos <= m) res = min(res, qry(lc[x], l, m, pos));
	else res = min(res, qry(rc[x], m + 1, r, pos));
	return res;
}
int merge(int x, int y, int l, int r) {
	if (!x || !y) return x + y;
	insert(x, l, r, p[y]);
	lc[x] = merge(lc[x], lc[y], l, m);
	rc[x] = merge(rc[x], rc[y], m + 1, r);
	return x;
}
void dfs(int u, int fa) {
	for (auto v : e[u]) {
		if (v == fa) continue;
		dfs(v, u);
		root[u] = merge(root[u], root[v], 1, N);
	}
	ans[u] = qry(root[u], 1, N, a[u] + M);
	if (ans[u] == inf) ans[u] = 0;
	t[u] = { b[u], ans[u] - b[u] * M };
	insert(root[u], 1, N, u);
}
#undef m
void mian() {
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	for (int i = 1; i <= n; i++) cin >> b[i];
	for (int i = 1; i < n; i++) {
		int u, v;
		cin >> u >> v;
		e[u].push_back(v);
		e[v].push_back(u);
	} 
	dfs(1, 0);
	for (int i = 1; i <= n; i++) cout << ans[i] << " \n"[i == n];
}
bool Med; 
int main() {
//	fprintf(stderr, "%.9lfMb\n", 1.0 * (&Mbe - &Med) / 1048576.0);
	ios :: sync_with_stdio(false);
	cin.tie(0), cout.tie(0); 
	int t = 1; 
	while (t--) mian();
//	cerr << 1e3 * clock() / CLOCKS_PER_SEC << "ms\n"; 
	return 0;
} 

标签:le,Leaf,int,LL,李超,节点,Through,calc,id
From: https://www.cnblogs.com/came11ia/p/18037843

相关文章

  • 这就是我们的李超线段树啊,你们有没有这样的李超线段树啊?
    沟槽的公式,真是公公又式式啊。考虑一个线段树节点维护一个线段(但一条线段可以被多个线段树节点维护),需要保证该节点被线段完全覆盖。每次添加一个线段的时候:如果当前节点没有被这个线段完全覆盖,那么直接递归左右儿子修改。如果当前节点的线段比新线段严格劣(也就是对于每一......
  • A trip through the Graphics Pipeline 2011: Index
    原文地址https://fgiesen.wordpress.com/2011/07/09/a-trip-through-the-graphics-pipeline-2011-index/Welcome.ThisistheindexpageforaseriesofblogpostsI’mcurrentlywritingabouttheD3D/OpenGLgraphicspipelinesasactuallyimplementedbyGPUs.Alot......
  • 李超线段树
    李超线段树线段树的扩展版本用来动态维护平面上直线支持插入直线/线段,查询横坐标某处覆盖的线中纵坐标最大/最小值可以用于斜率优化DP插入直线这里直线是线段树上维护的信息,表示当前区间中点处最优的直线同时相当于区间修改,直线也是标记,这个区间内都可能有这条直线但是标......
  • ABC340G Leaf Color
    题意给定一棵树\(T\),包含\(n\)个节点,每个节点有颜色。求有多少个\(T\)的导出子图\(T'\),满足\(T'\)中的叶子节点颜色相同。答案对\(998244353\)取模。\(n\le2\times10^5\)。分析由于叶子节点的限制极其特殊,考虑从叶子的角度思考问题。如果知道了叶子节点的集合,那......
  • 李超树
    李超树(不得不抱怨一下我现在正在用的这个键盘,好难打,如果有啥子笔误请指出)基础支持在线插入一条线段,一条直线,插入线段的极限时间复杂度是\(O(log^2)\),插入一条直线的时间复杂度是\(O(log)\)的。支持查询一个已知\(x\)的竖线与插入的直线段的交点的最值。实现与普通线段树......
  • Leaflet 实现自定义瓦片实现xyz信息和边框绘制到瓦片上
    Leaflet实现自定义瓦片的渲染,将一些信息和边框绘制到瓦片上。主要作用是创建一个Canvas元素作为Leaflet的瓦片,并在Canvas上绘制一些文本信息和边框。实现步骤:创建一个Canvas元素作为Leaflet的瓦片,并获取其2D绘图上下文。设置Canvas的大小为当前瓦片的大小。......
  • 「笔记」李超线段树
    目录写在前面引入线段区间修改单点查询完整代码例题P4254[JSOI2008]BlueMary开公司P3081[USACO13MAR]HillWalkG写在最后写在前面LiChaoTree也是LCT(智将和典中典之楼房重建都是\(O(\log^2n)\)地进行修改的样子,但是楼房重建是拆分完区间后再\(O(\log^2n)\)地向上......
  • 在vue2中使用leaflet.AnimatedMarker来移动某个目标
    需求是:点击某个按钮后让扫描仪沿着某条线移动进行扫描效果:  扫描仪是沿着河流移动的,河流的生成方式通过geojson数据生成,geojson里包含了河流的一些点位的经纬度,扫描仪根据经纬度来移动leaflet:1.9.4 leaflet.AnimatedMarker:1.0.0 1.引入 importLfrom'leaf......
  • thymeleaf—02—模板
    一、th:fragment模板片段我们可以使用模板,定义一些会经常复用的代码,使用th:fragment定义然后使用th:insert引入这个模板内容,或者使用th:replace进行内容替换;还有一个th:include标签也是引入模板内容,但是这个不推荐了; 除了增加模板,还可以使用th:remove进行模板的删除操作; ......
  • Eloquent 模型使用详解 Has One Through 远程一对一
    远程一对一也好,经过型,穿过型一对一也好,都能表示这种模型的关联方式:一种非直接的关系定义这里使用官方的例子:......