線段樹的懶操作 POJ1823

2021-09-03 10:43:50 字數 1522 閱讀 7671

本來以為把伸展樹看懂了,結果分析題目的時候,且不說自己做了,別人的**都讀不懂!看到伸展樹操作中也有懶操作的身影,就重新回到基礎,學習了一下線段樹的懶操作問題!

半天時間就這樣過去了!不過還好的是勉強ac了這道題!

這道題是一道線段樹很基礎的題:更新區間,查詢區間!題目大意是給定乙個區間,0表示空閒,1表示區間單元被佔據。問整個區間最大的連續子區間有多大?

記得以前做過類似的題目。線段樹結點需要以下的資訊:

struct tree; 

由於查詢的是整個區間的最大值,最後查詢的時候只需要輸出根結點的max即tree[1].max就可以了。

為了提高線段樹的效率,以相同的方式更新某區間時,(比如對整個區間同時add乙個數)並不去真正更新其子區間,而是以某種方式把這個操作記錄下來,等下一次訪問到該區間並需要訪問其子區間時,在訪問的同時把子區間的值進行更改!這種思想就稱為懶操作。

像poj的那道題就是典型的懶操作!

思路很簡單就不細說了,看**可能更容易理解:

/*

* intervaltree.cpp

**  created on: 2012-10-12

*      author: administrator

*/#include

#define max(a,b) (a)>(b)?(a):(b)

#define m 20000

struct tree; 

tree tree[4*m]; 

int n,p; 

void build(int id,int ll,int rr) 

void push_down(int id,bool sign)else 

} //更新區間

void update(int id ,int ll,int rr,bool sign) 

if(tree[id].occ!=-1)push_down(id,tree[id].occ);//執行到這行**意味著 tree[id]的子區間要更改了,所以需要執行一次push_down

if(rr<=tree[id].mid)else

if(ll>tree[id].mid)else 

//需要修改的就只有3個值:max,cl,cr 分別代表最長連續個數為多少,最左邊有多少個空閒,最右邊有多少個空閒

if(tree[id].occ==-1)else 

if(tree[2*id+1].occ==0)else 

//求tree[id].max

int len=tree[2*id].cr+tree[2*id+1].cl; 

tree[id].max=max(len,max(tree[2*id].max,tree[2*id+1].max)); 

}else 

if(tree[id*2].occ==tree[id*2+1].occ) 

tree[id].occ=tree[id*2].occ; 

} int main()else 

} return 0; } 

線段樹的懶操作 POJ1823

本來以為把伸展樹看懂了,結果分析題目的時候,且不說自己做了,別人的 都讀不懂!看到伸展樹操作中也有懶操作的身影,就重新回到基礎,學習了一下線段樹的懶操作問題!半天時間就這樣過去了!不過還好的是勉強ac了這道題!這道題是一道線段樹很基礎的題 更新區間,查詢區間!題目大意是給定乙個區間,0表示空閒,1表...

線段樹區間更新 poj 1823

題意 乙個旅館有n個房間,有m次操作,每次操作可以是 1,從第a個房間開始的連續b個房間全部住滿 2 從a開始的b個房間全部清空 3 查詢n個房間中最長連續空房間的長度。思路對於每個節點,記錄這個節點的sta 狀態,val 最長連續空房 lmx 區間內左側連續空房間數 rmx 區間內右側連續空房間數...

POJ2528 線段樹的區間操作

首先應該對該 0,10000000 進行離散化 即先將點集進行排序,然後從小到大縮小其中的間距,使得最後點數不會超過2 n 然後就是線段樹操作 只需進行染色,然後最後用nlgn進行乙個個查詢顏色記錄即可 include include int color 20005 4 a 20005 p 2000...