BZOJ2957 樓房重建 線段樹

2021-08-05 20:49:15 字數 1837 閱讀 6023

題目:

time limit: 10 sec  

memory limit: 256 mb

submit: 2259  

solved: 1069 [

submit][

status][

discuss]

小a的樓房外有一大片施工工地,工地上有n棟待建的樓房。每天,這片工地上的房子拆了又建、建了又拆。他經常無聊地看著窗外發呆,數自己能夠看到多少棟房子。

為了簡化問題,我們考慮這些事件發生在乙個二維平面上。小a在平面上(0,0)點的位置,第i棟樓房可以用一條連線(i,0)和(i,hi)的線段表示,其中hi為第i棟樓房的高度。如果這棟樓房上任何乙個高度大於0的點與(0,0)的連線沒有與之前的線段相交,那麼這棟樓房就被認為是可見的。

施工隊的建造總共進行了m天。初始時,所有樓房都還沒有開始建造,它們的高度均為0。在第i天,建築隊將會將橫座標為xi的房屋的高度變為yi(高度可以比原來大---修建,也可以比原來小---拆除,甚至可以保持不變---建築隊這天什麼事也沒做)。請你幫小a數數每天在建築隊完工之後,他能看到多少棟樓房?

第一行兩個正整數n,m

接下來m行,每行兩個正整數xi,yi

m行,第i行乙個整數表示第i天過後小a能看到的樓房有多少棟

3 42 43 6

1 1000000000

1 1111

2資料約定

對於所有的資料1<=xi<=n,1<=yi<=10^9

n,m<=100000

中國國家隊清華集訓 2012-2013 第一天 [

submit][

status][

discuss]

思路:

要使後面的能看到,就要保證後面的斜率大於前面斜率

1.對於左區間l與右區間r,如果l最大的斜率比r大,那麼r的所有樓房都會被擋住。所以答案就算l區間的答案。 

2.否則,如果r的左區間最大斜率比l的最大還要小,那麼只有r的右區間可能有答案,就遞迴尋找r的右區間的答案。 

3.如果r的左區間最大斜率比l的最大還要大,那麼r的右區間的所有都符合答案,但注意不是直接用r的右區間的答案,而是用r的答案-r的左區間的答案,再遞迴尋找r的左區間的答案。 

**:

#include #include #include #include #include #include #include #include #include #include #include #define mem(a,b) memset(a,b,sizeof(a))

#define inf 0x3f3f3f3f

#define n 100005

#define ll long long

using namespace std;

#define lson l,m,rt<<1

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

struct node

t[n<<2];

int query(int l,int r,int rt,double val)

void update(int p,int l,int r,int rt,double val)

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

if(p<=m)

update(p,lson,val);

else

update(p,rson,val);

t[rt].angle=max(t[rt<<1].angle,t[rt<<1|1].angle);

t[rt].see=t[rt<<1].see+query(rson,t[rt<<1].angle);

}int main()

return 0;

}

BZOJ2957 樓房重建(線段樹)

這裡放傳送門 可以發現如果一段樓房能被看見,那麼它們跟原點的連線的斜率都是單調遞增的。於是這就變成了乙個維護上公升序列的題。這裡的上公升序列不是最長上公升子串行那樣的東西,而是相當於貪心地選擇,選中的子串行中的每乙個元素它前面都不能存在大於等於它的元素。比如說,有乙個斜率序列是1,2,4,3,4,如...

bzoj2957樓房重建 線段樹

小a的樓房外有一大片施工工地,工地上有n棟待建的樓房。每天,這片工地上的房子拆了又建 建了又拆。他經常無聊地看著窗外發呆,數自己能夠看到多少棟房子。為了簡化問題,我們考慮這些事件發生在乙個二維平面上。小a在平面上 0,0 點的位置,第i棟樓房可以用一條連線 i,0 和 i,hi 的線段表示,其中hi...

線段樹 bzoj2957 樓房重建

大概意思就是求序列從一位置開始的動態上公升序列。分塊可過,但這一類題目其實可用線段樹。也就是維護每個區間的上公升序列長度。下面這種求法只是用於當前節點所覆蓋的區間完全被查詢區間覆蓋。具體而言,查詢時如果左兒子的max值 k,只去右兒子找。如果max lc k,那麼右兒子的長度全部符合,只要再遞迴著找...