洛谷 P4198 樓房重建

2022-09-10 00:48:29 字數 897 閱讀 3929

(區間最大可修改上公升)(線段樹做法,可以分塊亂搞)

這道題只是詢問1到n區間,其實可以改成任意區間的最大上公升。

首先注意題目是連線,因此不是高度上公升是斜率上公升(y/x),但在之後的說明中都會說斜率為高度,大家把他想象成在樓底向上仰望看到多少棟樓。

然後造樹,維護h,區間內最大的高度維護 s,區間內的最大上公升子串行。

每次更新時,一邊維護h和s,此時可能面臨求s如果求,此時就進入詢問,其s為左子樹的s和代入左子樹的最高值到右子樹查詢右子樹中比左子樹最高值大為起點的s

詢問時如果詢問的高度大於左子樹最大,詢問右子樹,否則找左子樹後將左子樹的最大高度代入右子樹來查詢。(如果右子樹的一些結點比左子樹最大高度小則不可能能看到)最後成功維護s

答案直接z[1].s

#define maxn 100005

#define midd ((z[p].b+z[p].a)>>1)

struct nodez[maxn<<3];

int n,m;

void maketree(int p,int l,int r)

int query(int p,double hh)

if(z[p<<1].h<=hh) return query(p<<1|1,hh);

else

}void update(int p,int x,double val)

if(x<=midd) update(p<<1,x,val);

else update(p<<1|1,x,val);

z[p].h=max(z[p<<1].h,z[p<<1|1].h);

z[p].s=z[p<<1].s+query(p<<1|1,z[p<<1].h);

}int main()

}

洛谷P4198 樓房重建

題意 給定序列,每次修改乙個值,求字首最大值的個數。解 線段樹經典應用。每個節點維護最大值和該區間字首最大值個數。發現我們不用下傳標記,只需要合併區間。需要實現乙個函式int ask l r lm 求出區間 l r 中前乙個數是lm時字首最大值個數。那麼當lm large ls 時,return a...

洛谷P4198 樓房重建 分塊

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

洛谷 P4198 樓房重建 題解

題面 首先你要知道題問的是什麼 使用一種資料結構,動態地維護以1為起點地最長上公升子串行 把樓房的高度轉化成斜率地序列 的長度 怎麼做?線段樹!初始化 對於每乙個葉子節點,從這段區間頭可以看到的樓房數量一定為1,區間斜率最大值一定為該點的斜率 在合併時 1.我們可以先查詢右區間的左區間的最大值,如果...