線段樹區間合併

2021-09-26 06:16:34 字數 2587 閱讀 8333

通過一道例題入門線段樹區間合併

例題:輸入n個 0,1數字.

操作 :

0 l r 查詢[l,r]區間,輸出最長連續1的長度;

1 l r x 修改[l,r]區間的值為x.

思路

區間資訊問題可以用線段樹,線段樹的基本模板,每個節點主要維護區間最長1串,sum.len。此外,區間合併時(push_up),我們要求的兩個子區間合併的最長1串,可以通過增加兩個節點資訊(下面還要講乙個clo),即:節點的從區間左右端點開始的1串長度, sum.llen , sum.rlen .這樣在求合併時,合併區間就是max(sum[lson].len , sum[rson].len , sum[lson].rlen+sum[rson].rlen )

演算法實現:我們用線段樹的每個節點儲存四個變數:

1.len 該區間中的最長1串.

2.llen 從左端點開始的最長1串.

3.rlen 從右端點開始的最長1串.

4.clo 標記改區間標記情況,

值為1:表示區間全為1,長度為r-l+1;

值為0: 表示區間全為0,沒有1

值為-1:其他情況.

clo類似懶標記

#include

#include

#include

#include

#include

#define lson (rt<<1)

#define rson (rt<<1|1)

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

using

namespace std;

const

int maxn=

1e5+20;

int a[maxn]

;struct acsum[maxn<<2]

;struct ans};

int lazy[maxn<<2]

;void

creat

(int rt,

int l,

int r,

int v)

void

push_up

(int rt,

int l,

int r)

void

push_down

(int rt,

int l,

int r)

}void

build

(int rt,

int l,

int r)

build

(lson,l,mid)

;build

(rson,mid+

1,r)

;push_up

(rt,l,r);}

void

update

(int rt,

int l,

int r,

int ll,

int rr,

int v)

push_down

(rt,l,r);if

(ll<=mid)

update

(lson,l,mid,ll,rr,v);if

(midupdate

(rson,mid+

1,r,ll,rr,v)

;push_up

(rt,l,r);}

ans query

(int rt,

int l,

int r,

int ll,

int rr)

push_down

(rt,l,r)

; ans q=

ans(0,

0,0)

,p=ans(0

,0,0

);if(ll<=mid) q=

query

(lson,l,mid,ll,rr);if

(midquery

(rson,mid+

1,r,ll,rr)

;return

ans(

max(

max(p.l,q.l)

,q.rl+p.ll)

, q.l==mid-l+

1? q.ll+p.ll : q.ll,

p.rl==r-mid ? q.rl+p.rl : p.rl );

}int

main()

build(1

,1,n);

scanf

("%d"

,&m)

;for

(int i=

1;i<=m;i++)if

(opt==0)

}return0;

}////4//1 0 1 1

//4//1 1 2 1

//0 1 2

//1 2 3 0

//0 1 4

//10

//1 0 1 1 1 0 1 0 1 1

//7//0 3 5

//0 1 5

//1 1 3 0

//0 1 5

//1 7 10 1

//1 6 6 1

//0 1 10

線段樹 區間合併

hdu 1540 tunnel wa re 詳細見 include include include include include define max 50010 define lson l,m,k 1 define rson m 1,r,k 1 1 using namespace std typ...

線段樹 區間合併

1 poj 3667 題意 支援兩種操作 1 如果有連續長度大於d的房間,則輸出最左的區間值,否則輸出0 2 將ql,qr區間的房間標記為 未入住 思路 節點維護三個域,該節點的最大房間數,該節點左端點起的最大房間數,該房間右端點起的最大連續房間數,用線段樹進行更新和查詢 include inclu...

線段樹 區間合併

線段樹的區間合併,即尋找 詢問區間中滿足條件的連續最長區間。而乙個區間連續的最長區間有兩種情況 1 此連續最長區間全在左子樹或全在右子樹,則sum t max sum t 1 sum t 1 1 2 一部分在左子樹,一部分在右子樹,則sum t suml t 1 1 sum t 1 因此,我們需要記...