通過一道例題入門線段樹區間合併
例題:輸入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 因此,我們需要記...