本題目重做感受頗多,
思考的深度決定了對線段樹的掌握程度,只有自己創生的才是自己的啊。
本題用到了三個維護值,sum表示區間最長連續區間,lsum為區間左面最長連續區間長。rsum同理。
現在來說明sum為什麼具有 可維護性,
線段樹的可維護性是相對於更新區間而言的,因為更新的logn個區間總是被刷成全空房間,或全滿房間,所以這幾個區間的三個屬性都可以得到維護,並且具有向上的合併性質
所以可以維護,一旦可以維護,那就啥也不說了。
#include #include #include #include #include using namespace std;
typedef long long ll;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define rep(i,n) for(int (i)=0;(i)<(n);i++)
#define rep(i,n) for(int (i)=1;(i)<=(n);i++)
const int n = 51111;
int sum[n<<2],col[n<<2],lsum[n<<2],rsum[n<<2];
void push_up(int l,int r,int rt)
void upd_one_seg(int l,int r,int rt,int f)
else
}void push_down(int l,int r,int rt)
}void build(int l,int r,int rt)
int m = (l+r)>>1;
build(lson);
build(rson);
push_up(l,r,rt);
}void update(int l,int r,int rt,int l,int r,int f)
push_down(l,r,rt);
int m = (l+r)>>1;
if(l<=m) update(lson,l,r,f);
if(r>m) update(rson,l,r,f);
push_up(l,r,rt);
}int query(int l,int r,int rt,int len)
push_down(l,r,rt);
int m = (l+r)>>1;
if(sum[rt<<1]>=len) return query(lson,len);
int mid = rsum[rt<<1]+lsum[rt<<1|1];
if(mid >= len)
else if(sum[rt<<1|1]>=len) return query(rson,len);
return 0;
}int n,m;
int main()
}else }}
return 0;
}
POJ 3667 線段樹 標記
自從某次考試寫線段樹寫掛了以後 這是第一次寫線段樹,這是乙個傷心的故事 題意 思路 標記 維護從左到右的最大值 從右到左的最大值 區間內的最大值 然後就一搞 就出來了 by siriusren include using namespace std int n,m,jy,xx,yy,d,d stru...
poj3667 線段樹(區間合併)
題意 有編號為1 n的n個房間,有兩種詢問 1.有人來訂連續的k間房,有的話返回第一間房的編號,否則返回0。2.有人退連續的從a開始的連續的k間房。1.該區間最大的連續空房數 2.該區間從最左邊起的最大的連續空房數 3.該區間從最右邊起的最大的連續空房數 根據以上三個資訊,每個非葉結點的資訊都可以由...
poj 3667 線段樹 區間合併
感想 沒有什麼說的了。越做線段樹越感覺自己水。這個我感覺自己就真坑了大家了。難的不會,簡單的也水不過了。哎,最近這是什麼情況啊!題目 題意 旅館有編號為1 n的房間,現在可能有m波人過了租房,每波人可能要定連續的d間房,如果有的話,編號盡量小,沒有的話就說0,也可能有d個人要退房,他們的房是連續的x...