EVERYTHING HAPPENS FOR TH|

wnsyou

园龄:2年4个月粉丝:19关注:16

2024-09-08 11:39阅读: 17评论: 0推荐: 0

李超线段树

OI-wiki Link

直线型

先看一种题型:

  • 给出 k,b,加入一条 y=kx+b 的直线。
  • 给出 a, 查询与 x=a 相交的直线中纵坐标最大/最小值。

似乎是一种区间修改,单点查询?考虑使用线段树维护。

但对于不同的 x,不同的 k,b 造成的效果不一定是呈现出一种“压制”的态势,可以是类似于对于 x<midk1x+b1>k2x+b2,反之 k1x+b1<k2x+b2

这种情况下就需要使用另外一种线段树——李超线段树。

基本构成

在每个节点存储一组 k,b,表示在 x=mid 的情况下,kx+b 可以取到最值。

但注意我这里的 k,b 不作为懒标记下传,采用的是永久化标记的写法。

可以使用动态开点来优化。

操作二

和传统线段树差别不大。由于是永久化标记的写法,只需要把从根节点到 [x,x+1) 的所有节点上的 k,b 都去更新一下答案即可。

为了避免查询无效的节点,如果当前节点没法继续走下去(即对应节点的 b 取到了极值),则直接退出即可。

操作一

假设当前节点为 id,区间对应 [l,r)注意是左闭右开。

  • 如果当前节点没有存储任何的 k,b (可以采取给 b 初始化为极大/极小值来解决),则直接赋值即可。
  • 否则,看对于 x=mid 时,当前节点和修改的 k,b 那种情况更优,将更优的存储在节点 id 上,更劣的作为修改的 k,b,注意不是直接舍弃。这时有三种情况。
    • k=trid.k,那么无论如何,也不可能用手上的 k,b 来更新答案,直接退出即可。
    • k>trid.k,如果是求最大值,则去试图更新 id×2+1,[mid,r),否则去试图更新id×2,[l,mid)
    • k<trid.k,如果是求最小值,则去试图更新 id×2+1,[mid,r),否则去试图更新id×2,[l,mid)

复杂度

加上上面所说的所有优化后,可以发现每条线段最多影响 1 个节点,所以空间复杂度是 O(n)

但查询仍有可能跑满 logV 层,所以时间复杂度是 O(nlogV) 的。

线段型

如果加入的不是直线而是一条在 [l,r) 的线段呢?

其实和上面差不多,但你需要找到那条线段对应每个的区间,再在这个区间内做一下直线型修改即可。

时间负杂度和空间复杂度都比上面多乘一个 logV

例题

contest

点击查看代码
// https://vjudge.d0j1a1701.cc/problem/Yosupo-segment_add_get_min
#include <bits/stdc++.h>
//#define _1 (__int128)1
//#define int long long
using namespace std;
using ll = long long;
void FileIO (const string s) {
freopen(string(s + ".in").c_str(), "r", stdin);
freopen(string(s + ".out").c_str(), "w", stdout);
}
const int P = 1e9;
const ll INF = 4e18;
struct SegTree {
int ls, rs, k;
ll b = INF;
} ;
int n, q, ndcnt = 1, op, x, l, r;
ll ans, y, b;
vector<SegTree> tr;
int ls (int id) {
if (!tr[id].ls) tr.push_back({}), tr[id].ls = ++ndcnt;
return tr[id].ls;
}
int rs (int id) {
if (!tr[id].rs) tr.push_back({}), tr[id].rs = ++ndcnt;
return tr[id].rs;
}
void modify (int id, int l, int r, int k, ll b, int x, int y) {
if (l > y || r <= x || b == INF) return ;
if (l >= x && r <= y + 1 && tr[id].b == INF) {
tr[id].k = k, tr[id].b = b;
return ;
}
int mid = l + (r - l) / 2;
if (l >= x && r <= y + 1 && 1ll * tr[id].k * mid + tr[id].b > 1ll * k * mid + b)
swap(tr[id].k, k), swap(tr[id].b, b);
if ((tr[id].k == k && tr[id].b <= b) || l + 1 == r)
return ;
if (!(l >= x && r <= y + 1) || tr[id].k < k) modify(ls(id), l, mid, k, b, x, y);
if (!(l >= x && r <= y + 1) || tr[id].k > k) modify(rs(id), mid, r, k, b, x, y);
}
void Query (int x) {
int id = 1, l = -P, r = P + 1;
while (1) {
ans = min(ans, 1ll * tr[id].k * x + tr[id].b);
int mid = l + (r - l) / 2;
if (mid > x && tr[id].ls) id = ls(id), r = mid;
else if (mid <= x && tr[id].rs) id = rs(id), l = mid;
else break;
}
}
signed main () {
ios::sync_with_stdio(0), cin.tie(0);
// FileIO("");
cin >> n >> q, tr.push_back({}), tr.push_back({});
for (int i = 1, k, x, y; i <= n; i++) {
cin >> x >> y >> k >> b;
modify(1, -P, P + 1, k, b, x, y - 1);
}
while (q--) {
cin >> op >> l;
if (op) {
ans = INF;
Query(l);
if (ans == INF) {
cout << "INFINITY\n";
continue;
}
cout << ans << '\n';
} else {
cin >> r >> x >> y;
modify(1, -P, P + 1, x, y, l, r - 1);
}
}
return 0;
}

本文作者:wnsyou の blog

本文链接:https://www.cnblogs.com/wnsyou-blog/p/18400703/li_chao_tree

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   wnsyou  阅读(17)  评论(0编辑  收藏  举报
  1. 1 勝利への道 安藤浩和
  2. 2 Minecraft’s End Eric Fullerton
  3. 3 月光曲完整版 贝多芬 云熙音乐
  4. 4 平凡之路 (Live版) 朴树
  5. 5 Minecraft C418
  6. 6 Paradise NiziU
  7. 7 叫我,灰原哀 龙大人不喷火
  8. 8 心机之蛙,一直摸你肚子 ——《名侦探柯南》原创同人曲 炊饭,叶辞樱,温海,寒砧,南柯柯,小茜玛姬,盛姝,阿崔Ac,贝壳初,千湛,兮茶子DaYu,乔慕,黎鹿北,起千温卿,遮阳伞,曲悠
  9. 9 战 歌 此去经年
Minecraft’s End - Eric Fullerton
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

I see the player you mean.

It is reading our thoughts as though they were words on a screen.

They used to hear voices.

Before players could read.

Sometimes disturbing.

Sometimes beautiful indeed.

Does it know that we love it?

That the universe is kind?

A million years ago,it still works

in the reality behind

and the universe said I love you

and the universe said you are the daylight

and the universe said you are not alone

and the universe said you are the night

Once we were called

the spirit of the mountain.

WHO ARE WE

Father sun

Mother moon

Gods demons angels aliens

the player,too.

WE ARE THE UNIVERSE.

We are EVERYTHING you think isn‘t you.

You are alive

ON A FLAT

INFINITE WORLD

generated by a source code

a million years old

and the universe said I love you

and the universe said you are the daylight

and the universe said you are not alone

and the universe said you are the night

Take a breath,now

Take another

Feel air in your lungs.

dreamed it was lost in a story.

and the game was over

Wake up.

加载中…

{{tag.name}}

{{tran.text}}{{tran.sub}}
无对应文字
有可能是
{{input}}
尚未录入,我来提交对应文字
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示