Learning 李超線段樹

2022-05-22 20:27:12 字數 1666 閱讀 7208

這玩意兒假啊!

大清早起來突然開始yy,線段樹怎麼區間加乙個等差數列,然後支援區間取max。yy無果,咕咕咕

後來,點開了一道雅禮集訓題,哇塞,真的有這種題哎,哇塞,是弱化版哎(只要支援單點取max就好了),但我還是不會做哎,涼涼涼。

進入正文,思想主要是每個區間用乙個「暴露」最多的線段進行替代,其餘的線段用乙個陣列記下來(因為是單點最值所以可以直接比較)。然後在加入線段的時候分類討論一下:

1、新線段完全高於舊線段,那麼把舊線段丟到陣列裡並覆蓋。

2、新線段完全低於舊線段,那麼直接無視。

3、新舊線段有交點,按交點分治下去。

時間複雜度:\(o(n log^2 n)\)

/*

bzoj3165

*/#include#include#include#include#includeusing namespace std;

const int mod1 = 39989;

const int mod2 = 1000000000;

const int maxn = 100000 + 10;

const int maxt = maxn << 2;

const double eps = 1e-9;

struct anode

anode(int _xa, int _ya, int _xb, int _yb):xa(_xa), ya(_ya), xb(_xb), yb(_yb)

else

}inline double f(int x)

}a[maxn];

inline int sgn(double x)

inline int cross(int x, int y)

//sgt

int n, t[maxt], pos[maxn], tot;

inline void updata(int x, int id) }

void ins(int u, int l, int r, int p, int q, int id)

int l = sgn(a[t[u]].f(l) - a[id].f(l)) < 0;

int r = sgn(a[t[u]].f(r) - a[id].f(r)) < 0;

if(l && r) t[u] = id;

else if(!l && !r)

else

if(tmp > mid && l)

if(tmp > mid && r) ins(rs,mid + 1,r,p,q,id);

}return;

}int mid = (l + r) >> 1;

if(p > mid) ins(rs,mid + 1,r,p,q,id);

else if(q < mid + 1) ins(ls,l,mid,p,q,id);

else }

inline int merge(int x, int y, int k)

int query(int u, int l, int r, int p)

else }

int main()

lastans = tmp;

printf("%d\n", lastans);

}if(op == 1)

}return 0;

}

李超線段樹

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

李超線段樹

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

李超線段樹

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