李超線段樹支援這樣的操作:
插入一條直線。
詢問與$x=x_0$相交的點的最大/小的縱座標(接下來我們以最大值為例)
它基於線段樹的標記永久化,也就是說,我們對於區間$[l,r]$維護$x=mid$上最高的直線的編號(但是如果$[l,r]$的所有點都以$[l,r]$的父親記錄的直線作為最大值,那麼$[l,r]$的子樹都沒有記錄的直線(這就是標記永久化)),然後詢問操作肯定沒有問題,重點就是新增直線了。
假設當前遞迴到$[l,r]$,要插入$k_1x+b_1$,之前記錄的直線為$k_2x+b_2$。
不妨設$k_1第一種情況:$k_1mid+b_1>k_2mid+b_2$,那麼更新$[l,r]$的標記,只向$[mid+1,r]$遞迴,因為$[l,mid]$上所有點都以$k_1x+b_1$作為最大值。
第二種情況:$k_1mid+b_1\leq k_2mid+b_2$,那麼不更新$[l,r]$的標記,只向$[l,mid]$遞迴,因為$[mid+1,r]$上所有點都以$k_2x+b_2$作為最大值。
這樣顯然更新一次是$o(\log^2 n)$的。(我也不知道我在想什麼。。。)
#include#define rint register intluogu4254using
namespace
std;
const
int n = 100003, m = 50000
;int
n, tot;
struct
line
} l[n];
int tag[m << 2
];inline
double query(int x, int l, int r, int
pos)
inline
void insert(int x, int l, int r, int
id)
int mid = l + r >> 1
;
if(l[tag[x]].k
else insert(x << 1 | 1, mid + 1
, r, id);
} else
else insert(x << 1
, l, mid, id);
}}int
main()
else}}
例題:cf1175g(如果認為難度落差太大,本人不負責)
李超線段樹學習筆記
至今不會李超線段樹 jpg 先說明一下,李超線段樹只能解決 只插入 的問題,如果有刪除恕它無能為力 先考慮這麼乙個問題,我們要資瓷動態插入直線以及詢問直線 x k 與其它所有直線相交的點中最大的 y 座標是多少 李超線段樹的具體過程是這樣的 對於乙個區間,我們維護該區間的所有直線中,從上往下去看可以...
李超線段樹學習筆記
至今不會李超線段樹 jpg 先說明一下,李超線段樹只能解決 只插入 的問題,如果有刪除恕它無能為力 先考慮這麼乙個問題,我們要資瓷動態插入直線以及詢問直線 x k 與其它所有直線相交的點中最大的 y 座標是多少 李超線段樹的具體過程是這樣的 對於乙個區間,我們維護該區間的所有直線中,從上往下去看可以...
李超線段樹
首先來看一道題 heoi2013 segment 可以發現的是,實質上某個 x k 處的最大值只有乙個,因此我們需要盡可能減少計算不優的線段。那麼對於兩條線段 a,b a ne b 它們左右端點橫座標相同,就只會產生如下四種情況 從特殊情況出發,每次我們都插入一條 1,n 的線段。如果是前兩條情況,...