poj 3667 線段樹前字尾區間 Hotel

2021-06-09 14:17:06 字數 1695 閱讀 5913

【題意】

一共有n個空位,初始全為空,會有兩種操作,一種是詢問是否有r個連續的空位,若有,則將最左端有r個連續的空位的地方全部填滿,若沒有則不填,另一種是將從u開始的d個位置全部清空

【輸入】

第一行兩個數n、m(<=50000),表示n個空位,m次操作

接下來m行每行表示一次操作,

若該行第乙個數字為1,接下來是乙個數字,表示操作一

若該行第乙個數字為2,接下來是兩個數字,表示操作二

【輸出】

對於每個操作一,若存在r個連續的空位,則輸出最靠左的r個連續空位的起點,若不存在則輸出0

解:用lsum表示當前區間最長連續字首的長度,rsum表示當前區間最長連續字尾的長度,msum表示本個區間最長連續段的長度。重點是還有乙個cover,-1表示這個區間既有非空的,又有空的; 1 表示整個當前區間都滿了; 0 表示整個區間都空了。 就是lazy。 

查詢的時候,首先,得滿足有這樣連續的長度。其次:

如果當前區間字首長度就大於等於我們想要的長度的話,就返回左端點。 

如果左孩子的最長長度》=wanted的話,就去左孩子裡面找。

如果包含m的連續區間》=wanted的話,就直接返回左孩子字尾的最左端。

不然,就只能去右孩子裡面找了。

做題過程:

開始沒有cover,沒有push_dn,就只有乙個push_up。 想來更新的時候不是沒有更新到底嗎,也就是說孩子還沒更新呢,所以一定得有cover的呀。

現在再一想,果然表示當前區間是線段樹的根本,我怎麼給忘了呢。。。

/*

pro: 0

sol:

date:

*/#include #include #include #include #include #include #include #include #define maxn 50010

#define lson l,m , rt << 1

#define rson m + 1, r , rt << 1 | 1

#define ls rt << 1

#define rs rt << 1 | 1

int n,q,a,b,op;

using namespace std;

int lsum[maxn << 2], rsum[maxn << 2], msum[maxn << 2], cover[maxn << 2];

void build(int l, int r, int rt)

void push_dn(int rt, int m)

}void push_up(int rt,int m)

//int query(int dis, int l, int r, int rt)

int query(int dis, int l, int r, int rt)

void update(int l,int r, int sign, int l, int r, int rt)push_dn(rt,r - l + 1);

int m = (l + r) >> 1;

if(l <= m) update(l,r,sign,lson);

if(r > m) update(l,r,sign,rson);

push_up(rt,r - l + 1);//

}int main()

}else}}

return 0;

}

poj3667 線段樹(區間合併)

題意 有編號為1 n的n個房間,有兩種詢問 1.有人來訂連續的k間房,有的話返回第一間房的編號,否則返回0。2.有人退連續的從a開始的連續的k間房。1.該區間最大的連續空房數 2.該區間從最左邊起的最大的連續空房數 3.該區間從最右邊起的最大的連續空房數 根據以上三個資訊,每個非葉結點的資訊都可以由...

poj 3667 線段樹 區間合併

感想 沒有什麼說的了。越做線段樹越感覺自己水。這個我感覺自己就真坑了大家了。難的不會,簡單的也水不過了。哎,最近這是什麼情況啊!題目 題意 旅館有編號為1 n的房間,現在可能有m波人過了租房,每波人可能要定連續的d間房,如果有的話,編號盡量小,沒有的話就說0,也可能有d個人要退房,他們的房是連續的x...

線段樹區間合併poj3667

題意 1 a表示如果有長度為a的連續的空房間,則占用 2 a b表示清空 a,a b 1 的房間 思路 線段樹區間維護,除了考慮區間上最大空房間,還要維護左邊最大連續和右邊最大連續 include include include include using namespace std define ...