這東西有點噁心啊,搞了好久才懂一點。
1.有什麼用?
對於乙個區間\([l,r]\)每個點可以取的權值符合表示式:\(y=kx+b\)的線段
有k條線段覆蓋在所有點上,可以動態插入線段,求每個時刻某個點或某個區間的最大/最小值。
它的思想是:盡可能不將優勢線段下傳,
2.什麼叫優勢線段?(假如是使每個點的值最大)
就是使區間內的取最大值的點最多的線段(當然,我們每次在實際操作中只是將優勢線段與插入線段進行比較,這裡的多條線段只是為了方便理解,兩條線段的圖如下:)
3.如何實現?
我們可以分成4種情況討論:(以最大值為標準)
\(<1>.\)插入線段的斜率大於原有優勢線段:
\((1).\)交點在區間中點左邊:
顯然,優勢線段改為插入線段,但原優勢線段可能在左子區間更優,遞迴。
此時中點處y值插入線段大於原優勢線段。
\((2).\)交點在區間中點右邊:
插入線段在此區間沒有原優勢線段優,但在右子區間有希望更優,遞迴。
此時中點處y值插入線段小於原優勢線段。
\(<2>.\)插入線段的斜率小於原有優勢線段:
\((1).\)交點在區間中點左邊:
插入線段在此區間沒有原優勢線段優,但在左子區間有希望更優,遞迴。
此時中點處y值插入線段小於原優勢線段。
\((2).\)交點在區間中點右邊:
顯然,優勢線段改為插入線段,但原優勢線段可能在右子區間更優,遞迴。
此時中點處y值插入線段大於原優勢線段。
修改大概就這樣,下面是**:
單點修改:
void update(int l,int r,int id,int x)
int mid=l+r>>1;
if(line[tag[x]].p>line[id].p)
if(line[tag[x]].p>line[id].p)
但是如果是區間查詢則要加上維護區間最小值/最大值的陣列:
十分麻煩,是我太蒟蒻了
首先我們要明確區間的最值一般都在兩端,
所以我們有些 沒有更新下去的要自我用兩端的最值更新,
void update(int l,int r,int p,int q,ll k,ll b,int x)
由於我們優勢線段能不下傳就不下傳,
所以使某點/某區間最優的線段可能在父區間上,
故要用父區間的和它比較。
單點查詢:
double query(int l,int r,int p,int x)
區間查詢:
ll query(int l,int r,int p,int q,int x)
if(p<=mid) ans=min(ans,query(l,mid,p,q,lc));
if(q>mid) ans=min(ans,query(mid+1,r,p,q,rc));
return ans;
}
李超樹 學習筆記
最近做多校聯賽的時候,遇到了一道不會做的題,題解上寫需要用到李超樹,所以就去學習了一下。參考部落格 李超樹的經典題目是bzoj的1568。在乙個平面裡面,有兩種操作 1.每次在乙個平面插入乙個條直線 給出兩個端點 x0,y0 和 x1,y1 2.詢問與x k的相交的直線中,最上面的直線是哪一條。對於...
李超樹學習筆記
其實很早就有這些這個的慾望了。但是由於種種原因 包括班主任 一直咕到現在。咕咕咕。不能再咕下去了!於是熬夜來寫這個。先看乙個例題 bzoj1568 jsoi2008 blue mary開公司 其實這個算是裸題了。當然我做的第一道李超樹的題不是這個。題目要求區間內的所有直線的最高點的最大值。並且帶插入...
李超線段樹學習筆記
至今不會李超線段樹 jpg 先說明一下,李超線段樹只能解決 只插入 的問題,如果有刪除恕它無能為力 先考慮這麼乙個問題,我們要資瓷動態插入直線以及詢問直線 x k 與其它所有直線相交的點中最大的 y 座標是多少 李超線段樹的具體過程是這樣的 對於乙個區間,我們維護該區間的所有直線中,從上往下去看可以...