李超

CF1303G(点分治+李超线段树)

随声附和 提交于 2020-02-28 20:31:23
CF1303G (点分治+李超线段树) 题目大意 给你一棵 n 个点的带点权的树,你需要求出树上的一个路径 \(x_1,x_2,\ldots,x_k,最大化 \sum_{i=1}^kia_{x_i}\) ,求最大权值。 数据范围 \(2\le n\le 150000\) 一条最大的路径并不好考虑如何直接求得, 我们试图把它用两条路径来合并 把一条过点 \(x_k\) 的路径 \(x_1, x_2, x_3\cdots x_{k-1},x_k ,x_{k+1}\cdots x_n\) 看成两条 \(x_1, x_2, x_3\cdots x_{k-1}\) 权值为 \(V_1\) 长度为 \(l_1\) , 和为 \(S_1\) \(x_k ,x_{k+1}\cdots x_n\) \(V_2, l_2, S_2\) 那么 \(V=V_1+V_2 + S_2*l_1\) 既然是可 \(O(1)\) 合并的, 又不难枚举, 可以想到用点分治来枚举中间点 但我们可能要和一堆路径合并, 怎么找到对于我手中已经有的一段路径找到另一条和它权值和拼起来最大的路径呢? 观察发现, 想一次函数, 把 \(l_1\) 看做 \(x\) , S看做k, 那就是找到一个一次函数 \(y = S_2 * x + V_2\) , 使 \(x = l_1\) 最大吗, 这个可以用李超线段树做 来源: https

CF932F(李超线段树+dp)

☆樱花仙子☆ 提交于 2020-02-07 00:38:42
CF932F(李超线段树+dp) 此题又是新玩法, 李超线段树合并优化 \(dp\) 一个显然的 \(\Theta(n^2)dp\) : \(dp[x]\) 表示从x出发到叶子节点的最小代价 \(dp[x] = \min(dp[y] + a[x] * b[y]) ~~(y \in subtree(x))\) 如果我们将 \(b[y]\) 看成斜率, \(dp[y]\) 看成纵截距, \(a[x]\) 看成横坐标, 那么问题转为了在平面上有一些直线, 选出与直线 \(x = a[x]\) 相交的最靠下的点吗, 李超线段树板题, 但这道题出到了树上所以要用上线段树合并 因为有负数所以要整体右移一下, 相应的直线也需变换, 具体见代码 代码: #pragma GCC optimize(3) #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define re register #define ll long long using namespace std; template <typename T> void read(T &x) { x = 0; bool f = 0; char c = getchar(); for (;!isdigit(c);c=getchar()) if

大约是一颗李超线段树

孤街醉人 提交于 2019-12-04 10:46:35
%%% 李 超 由于观看 J oe 大神 颓废 学习发现了这种高级数据结构 才引来了这场灾难(我先改完T2才改完T1 说明书: 用途:维护最优一次函数 复杂度:$\Theta (n log_{2}n^{2})$ 食 使用指南: 我们先把线段树节点中存储的信息改为存储一条线 存储的线段不一定在区间的每个点上都最有,但是应该是在该区间最优的 有没有感觉很像 二维MLE线段树 当然也可能有这么两条线分别在同一区间不同位置最优 此时维护优的区间更长的 (以下假设维护最大值 区间修改:   我们考虑两根线段   首先我们要将线段在线段树上定位,此时会有$ log_{2}n$个区间需要修改   接下来我们只考虑一个区间了哈   经对两根线段的相对位置大力分类讨论得:   一共有四种情况   1.        线段$a$(蓝色)的斜率比当前最优线段$b$(或许是橙色)小   且两线段交点在中点右侧   那么显然对于当前区间以及左侧区间线段$a$更优,   递归到这里就可以停了(当前区间已经被修改后再去修改左侧区间毫无意义   但是对于右侧区间   线段$b$仍可能更优   此时应以线段$b$为参数递归修改右侧区间   2.       线段$a$(同上)的斜率比当前最优线段$b$(同上)小   且两线段交点在中点左侧   线段$a$仅在左侧区间可能更优   此时应以线段$a

总结-李超线段树

匿名 (未验证) 提交于 2019-12-03 00:14:01
李超线段树可用来维护直线关系,支持: 加入一条直线 询问单点对应最优直线 结构与普通线段树类似,但更多分情况讨论 模板 #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #define R ( a , b , c ) for ( register int a = ( b ); ( a ) <= ( c ); ++( a )) #define nR ( a , b , c ) for ( register int a = ( b ); ( a ) >= ( c ); --( a )) #define Fill ( a , b ) memset ( a , b , sizeof ( a )) #define Swap ( a , b ) (( a ) ^= ( b ) ^= ( a ) ^= ( b )) #define ll long long #define u32 unsigned int #define u64 unsigned long long #define ON_DEBUGG #ifdef ON_DEBUGG #define D_e_Line printf ( "\n----------\n" ) #define D_e ( x )