本來以為把伸展樹看懂了,結果分析題目的時候,且不說自己做了,別人的**都讀不懂!看到伸展樹操作中也有懶操作的身影,就重新回到基礎,學習了一下線段樹的懶操作問題!
半天時間就這樣過去了!不過還好的是勉強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...