BZOJ2957 樓房重建

2021-09-11 01:14:20 字數 1421 閱讀 9262

題意:

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

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

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

%%% hzwer orz

看懂了題解 : 由於並不是單純的平視 所以變化高度時變成y/x (畫圖即證) 考慮修改某值時只對後面的答案有影響,所以用線段樹維護每個區間區間最大值,以及只考慮這個區間時,右兒子有多少個數滿足條件。當區間前面有別的數時,將前面的最大值與左兒子的最大值比較。如果前面的大就直接往右遞迴,否則往左遞迴。修改也是類似的。改了某值後不僅更新區間最大值,且區間最大值的改變對右邊的區間的答案的影響,遞迴計算。

時間複雜度o(mlog2n)

#include

using namespace std;

const

int maxn=

1000100

;struct jkxt[maxn*4+

100]

;int n,m;

void

build

(int k,

int l,

int r)

intsearch

(int k,

double maxx)

void

change

(int k,

int x,

double v)

int mid=

(t[k]

.l+t[k]

.r)/2;

if(x<=mid)

change

(k*2

,x,v)

;else

change

(k*2+1

,x,v)

; t[k]

.maxx=

max(t[k*2]

.maxx,t[k*2+

1].maxx)

; t[k]

.ans=t[k*2]

.ans+

search

(k*2+1

,t[k*2]

.maxx);}

//看懂題解從hzwer

intmain()

return0;

}

bzoj 2957 樓房重建

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

BZOJ2957 樓房重建

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

BZOJ2957 樓房重建

題意 給定m m 100000 個操作,每次將座標軸上橫座標為x 1 x n 100000 的樓的高度設為y,之後回答在 0,0 能看到幾個樓。分析 7.19考試題,當時全場基本都寫得o nm 大暴力,gzz神犇用騙分法竟然ac了,但在bzoj上tle了,只能說考試時候資料水了。這題有兩種做法,一種...