[CF932F]Escape Through Leaf 题意:给你一棵n个点的树,每个点有树形ai和bi,如果x是y的祖先,则你可以从x花费$a_x\times b_y$的费用走到y(费用可以为负).对于每个点,求从这个点开始走到某个叶子节点的最小费用. $n\le 10^5,|a_i|,|b_i|\le 10^5$ 题解:用f[x]表示x的答案,显然f[x]=min{f[y]+a[x]*b[y]}是一个凸包,我们可以用set维护凸包,到时候自底向上做一次启发式合并就行了(也可以线段树合并).…
CF932F Escape Through Leaf 首先, $ O(n^2) $ dp 是很显然的,方程长这样: \[dp[u] = min\{dp[v] + a_u\times b_v\} \] 这个方程看起来就很斜率,当我们写成了斜率优化的形式大概是这样的: \[\frac{dp[v]-dp[j]}{a_v-a_j} < -b_u \] 我们想通过这个式子做就必须维护动态凸包以及凸包的合并.这个东西是很恼火的,可能用 set 和 splay 啥的可以搞,可惜不大会. 这里就引入了一种科技,…
传送门 \(DP\) 设\(f_i\)表示第\(i\)个节点的答案,\(S_i\)表示\(i\)的子节点集合,那么转移方程为\(f_i = \min\limits_{j \in S_i} \{a_i \times b_j + f_j\}\) 这是一个很明显的斜率优化式子,斜率为\(b_j\),截距为\(f_j\),自变量为\(a_i\).考虑到斜率没有单调性,所以使用set维护凸包. 使用set维护凸包比较简单.一条直线插入时,先判断这条线段在当前凸包中是否合法,然后不断把两边不合法的直线删去.…
SB 题. 写出 DP 方程:\(f_i\) 表示从 \(i\) 跳的最小值. \(i\) 是叶子就是 \(0\),否则就是选个子树中的 \(v\),\(f_i=\min(f_v+a_ib_v)\). 至于优化,求出每个子树中的凸包就行了.启发式合并保证复杂度. 复杂度 \(O(n\log^2 n)\). 没错,我又用了回家路线那又臭又长的写法. #include<bits/stdc++.h> using namespace std; typedef long long ll; const i…
考虑链的做法,显然将两部分各自从大到小排序后逐位取max即可,最后将根计入.猜想树上做法相同,即按上述方式逐个合并子树,最后加入根.用multiset启发式合并即可维护.因为每次合并后较小集合会消失,总复杂度O(nlogn).场上并没有被启发得到这个优美的贪心. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #incl…
题面 传送门 题解 为什么成天有人想搞些大新闻 这里写的是\(yyb\)巨巨说的启发式合并的做法(虽然\(LCT\)的做法不知道比它快到哪里去了--) 建出\(SAM\),那么两个前缀的最长公共后缀就是它们在\(parent\)树上的\(LCA\)的深度 对于每一个子串来说,所有和它相同的串里只有它的前驱和它的后继是有贡献的.这个只要考虑任何一个包含了这个子串和另外一个和它相同的子串的询问,这个询问必定包含它的前驱或后继 那么我们用\(set\)启发式合并来维护\(endpos\)集合,每一次只…
听说正解是啥 set启发式合并+维护凸包+二分 根本不会啊 , 只会 李超线段树合并 啦 ... 题意 给你一颗有 \(n\) 个点的树 , 每个节点有两个权值 \(a_i, b_i\) . 从 \(u\) 跳到 \(v\) 的代价是 \(a_u \times b_v\) . 你需要计算每个节点跳到叶子的最小代价 . \((n \le 10^5, -10^5 \le a_i, b_i \le 10^5)\) 题解 我们首先考虑一个很容易的 \(dp\) , 令 \(dp_i\) 为 \(i\)…
题目描述 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失,而B国的国土也将归A国管辖.A国国王为了加强统治,会在A国和B国之间修建一条公路,即选择原A国的某个城市和B国某个城市,修建一条连接这两座城市的公路. 同样为了便于统治自己的国家,国家的首都会选在某个使得其他城市到它距离之和最小的城市,这里的距离是指需要经过公路的条数,如果有多个这样的城市,编号最小…
题意:一个带点权的森林,要求维护以下操作: 1.询问路径上的点权K大值 2.两点之间连边 n,m<=80000 思路:如果树的结构不发生变化只需要维护DFS序 现在因为树的结构发生变化,要将两棵树合并,这步可以用启发式合并,将比较小的树暴力连接到较大的树上面 离线的LCA算法无法维护,而倍增可以合并,所以用倍增求LCA 其余就是主席树,维护根到点的权值线段树就行了 机房里的罗爷爷写法比我高到不知道哪里去了 #include<cstdio> #include<algorithm>…
这道题目太神啦! 我们考虑他的每一次合并操作,为了维护两棵树合并后树的重心,我们只好一个一个的把节点加进去.那么这样一来看上去似乎就是一次操作O(nlogn),但是我们拥有数据结构的合并利器--启发式合并,那么我们就可以在均摊O(log2n)的时间内合并一颗树,这题就可以完美的AC啦! 什么,你问怎么维护重心?我们可以记录一个值sb表示子树的大小.怎么维护sb呢?我们可以采用打标记的方法,把新加入的节点到根的路径上的点的sb值都+1 对于维护答案,我们维护一个sm变量,来保存子树内所有节点到这个…