李超線段樹 總結

2022-06-20 14:09:17 字數 1623 閱讀 2861

李超線段樹可以支援如下操作:

在區間\(l~r\)加入線段\(y=kx+b\)。

詢問直線\(y=x\)與所有線段交點的\(y\)座標最值。

例題:模板題

如果該區間沒有線段或在此區間內,兩條線段沒有交點,則直接修改,不是最優的線段扔掉。

否則,在無視其它所有線段的情況下,計算出交點,並判斷哪條更優,把另一條下放到交點所在的兒子區間上。

由於每條線段最多下放\(o(logn)\)次,所以時間複雜度\(o(nlog^2n)\)。

詢問操作就是在所有包含它的區間的最優線段中找最優的。

有些類似標記永久化。

**很好寫(luogu4097):

#include #include double eps = 1e-5;

struct line

line(double k, double b, int bh)

line(int x1, int y1, int x2, int y2, int bh)

double f(int x)

};line zd[1600010];

bool bk[1600010];

double getjd(line a, line b)

bool check(line a, line b, int l, int r, int m, double x)

void pur(int i, int l, int r, line a)

double x = getjd(a, zd[i]);

if (x < l || x > r)

int m = (l + r) >> 1;

if (check(zd[i], a, l, r, m, x))

if (l < r)

zd[i] = a;

}void insert(int i, int l, int r, int l, int r, line a)

int m = (l + r) >> 1;

insert(i << 1, l, m, l, r, a);

insert((i << 1) | 1, m + 1, r, l, r, a);

}int getma(int i, int l, int r, int k, double & z) else

if (l == r) return rt;

int m = (l + r) >> 1,t;

double tz;

if (k <= m) t = getma(i << 1, l, m, k, tz);

else t = getma((i << 1) | 1, m + 1, r, k, tz);

if (tz > z || (fabs(tz - z) < eps && t < rt))

return rt;

}int ma[40010],wz[40010];

int main() else

if (x0 == x1)

}insert(1, 1, 39989, x0, x1, line(x0, y0, x1, y1, m));

} }return 0;

}

李超線段樹

首先來看一道題 heoi2013 segment 可以發現的是,實質上某個 x k 處的最大值只有乙個,因此我們需要盡可能減少計算不優的線段。那麼對於兩條線段 a,b a ne b 它們左右端點橫座標相同,就只會產生如下四種情況 從特殊情況出發,每次我們都插入一條 1,n 的線段。如果是前兩條情況,...

李超線段樹

t4正解李超線段樹?不會,滾過來學 貌似思路並不是很難的亞子 我們可以使用權值線段樹!對於每個區間,我們維護乙個最優線段 顯然對於乙個線段完全覆蓋的區間我們才處理 分四種情況討論 直接賦值 直接賦值 直接滾粗 最複雜的情況,我們考慮將覆蓋該區間最長的線段保留為最優線段 欸嘿?怎麼搞呢?其實只需判斷該...

李超線段樹

可以處理二維平面上加入線段,然後查詢單點最大值。首先我們定義乙個區間的最優勢線段,為區間中點值最大的線段,然後我們發現處理詢問,我們只需要將經過的線段樹節點上的最優勢線段對應的點值取max即可。然後考慮如何處理修改,首先將線段劃分到 o logn 個線段樹節點上。如果當前線段被最優勢線段完全覆蓋,那...