Segment Tree Beats 學習筆記

2021-10-03 02:38:57 字數 4734 閱讀 1087

模板題:

hdu5306

維護最大值,最大值個數,次大值,區間和即可。

區間更新k的時候,若當且節點最大值小於k則直接返回,k小於最大值且大於次大值時則可以直接更新區間和和最大值,否則繼續遞迴左右兒子,注意要把資訊更新到當前節點的所有祖先節點。

節點資訊向下傳遞的時候,祖先的歷史最小值顯然大於等於當前的次小值,所以只要祖先的歷史最小值小於當前節點的最大值,就要把當前節點更新一下。

#include

using

namespace std;

typedef

long

long ll;

const

int n =

1e6+10;

#define fi first

#define se second

#define pb push_back

#define mid (l+r>>1)

#define ls o<<1

#define rs o<<1|1

ll t[n<<2]

;int mx[n<<2]

,cm[n<<2]

,cnm[n<<2]

,n,a[n]

;void

push_up

(int o,

int l,

int r)

else

if(mx[ls]

)else

}void

build

(int o,

int l,

int r)

build

(ls,l,mid)

;build

(rs,mid+

1,r)

;push_up

(o,l,r);}

void

turn_min

(int o,

int l,

int r,

int d)

void

push_down

(int o,

int l,

int r)

voidup(

int o,

int l,

int r,

int x,

int y,

int d)

}push_down

(o,l,r);if

(x<=mid)

up(ls,l,mid,x,y,d);if

(y>mid)

up(rs,mid+

1,r,x,y,d)

;push_up

(o,l,r);}

int _;

ll get_sum

(int o,

int l,

int r,

int x,

int y)

intget_max

(int o,

int l,

int r,

int x,

int y)

intmain()

else

if(o==1)

else}}

return0;

}

bzoj4695

6個操作。

需要注意的是,如果最小值和最大值相等的話,就把次小值和次大值都重置一下,變成inf,-inf。

#include

using

namespace std;

typedef

long

long ll;

const

int n =

5e5+10;

#define fi first

#define se second

#define pb push_back

int n,a[n]

,q;inline

intread()

while

(ch<

'0'||ch>

'9');do

while

(ch>=

'0'&&ch<=

'9')

;return f*x;

}int mx[n<<2]

,mn[n<<2]

;//最大 最小

int laz[n<<2]

;//區間加

int cn[n<<2]

,cm[n<<2]

;//次大 次小

int cmx[n<<2]

,cmn[n<<2]

;//最大值個數 最小值個數

ll t[n<<2]

;#define mid (l+r>>1)

#define ls o<<1

#define rs o<<1|1

void

push_up

(int o,

int l,

int r)

else

if(mx[ls]

)else

if(mn[ls]

)else

if(mn[ls]

>mn[rs]

)else

return;}

void

build

(int o,

int l,

int r)

build

(ls,l,mid)

;build

(rs,mid+

1,r)

;push_up

(o,l,r);}

void

push_tag

(int o,

int l,

int r,ll d)

void

turn_max

(int o,

int l,

int r,

int d)

else cm[o]

=max

(cm[o]

,d);

}void

turn_min

(int o,

int l,

int r,

int d)

else

}void

push_down

(int o,

int l,

int r)

if(mx[ls]

>mx[o]

)turn_min

(ls,l,mid,mx[o]);

if(mx[rs]

>mx[o]

)turn_min

(rs,mid+

1,r,mx[o]);

if(mn[ls]

)turn_max

(ls,l,mid,mn[o]);

if(mn[rs]

)turn_max

(rs,mid+

1,r,mn[o]);

}void

add(

int o,

int l,

int r,

int x,

int y,ll d)

push_down

(o,l,r);if

(x<=mid)

add(ls,l,mid,x,y,d);if

(y>mid)

add(rs,mid+

1,r,x,y,d)

;push_up

(o,l,r);}

void

bemax

(int o,

int l,

int r,

int x,

int y,ll d)

}push_down

(o,l,r);if

(x<=mid)

bemax

(ls,l,mid,x,y,d);if

(y>mid)

bemax

(rs,mid+

1,r,x,y,d)

;push_up

(o,l,r);}

void

bemin

(int o,

int l,

int r,

int x,

int y,ll d)

}push_down

(o,l,r);if

(x<=mid)

bemin

(ls,l,mid,x,y,d);if

(y>mid)

bemin

(rs,mid+

1,r,x,y,d)

;push_up

(o,l,r);}

ll getsum

(int o,

int l,

int r,

int x,

int y)

intgetmax

(int o,

int l,

int r,

int x,

int y)

intgetmin

(int o,

int l,

int r,

int x,

int y)

intmain()

else

if(o==2)

else

if(o==3)

else

if(o==4)

else

if(o==5)

else

}return0;

}

Segment Tree Beats 區間最值問題

線段樹一類特殊技巧!引出 cf671c ultimate weirdness of an array 其實是考試題,改題的時候並不會區間取最值,區間求和,之後秉承著好好學習的態度,學習了segment tree beats 套路是維護出區間最小值和次小值,以及區間最小值數量。之後再維護出題目中需要的...

C Primer Chapter One學習筆記

筆記 1.流 從io裝置上讀入或寫出的字串行,用來說明字元隨時間順序生成或消耗。2.輸入輸出符可連用原因 operator 或operator 返回stream物件。3.要測試程式那個語句出錯,使用cout 4.新建乙個內建型別,如int i 0 最好先初始化,不然用到的時候沒初始化會產生奇怪的錯誤...

BroadcastReceiver學習筆記

需要注意 的是,不要在 onreceive 方法中新增過多的邏輯或者進行任何的耗時操作,因為在廣播接收 器中是不允許開啟執行緒的,當 onreceive 方法執行了較長時間而沒有結束時,程式就會報錯。有序broadcast,sendorderedbroadcast intent,null abort...