洛谷 P4198 樓房重建 題解

2022-07-13 20:09:15 字數 1107 閱讀 2105

題面

首先你要知道題問的是什麼:

使用一種資料結構,動態地維護以1為起點地最長上公升子串行(把樓房的高度轉化成斜率地序列)的長度;

怎麼做?線段樹!

初始化:

對於每乙個葉子節點,從這段區間頭可以看到的樓房數量一定為1,區間斜率最大值一定為該點的斜率;

在合併時:

1.我們可以先查詢右區間的左區間的最大值,如果右區間的左區間的最大值

比左區間的最大值小,那麼右區間的左區間

的所有答案一定看不到,所以我們就可以遞迴查詢右區間的右區間

2.如果右區間的左區間的最大值比左區間的最大值大,那麼原來被右區間的左區間擋住的現在一樣會被擋住,我們就可以加上右區間的右區間的答案,所以我們可以遞迴查詢右區間的左區間

時間複雜度是o(nlog^2n);

#include #define inc(i,a,b) for(register int i=a;i<=b;i++)

using namespace std;

class segmenttree[2000010];

int query(int k,int l,int r,double goal)

if(l==r)

int mid=(l+r)/2;

if(tree[k<<1].maxn<=goal)

else

} void change(int k,int l,int r,int goal,double value)

int mid=(l+r)/2;

if(goal<=mid) change(k<<1,l,mid,goal,value);

else change(k<<1|1,mid+1,r,goal,value);

tree[k].maxn=max(tree[k<<1].maxn,tree[k<<1|1].maxn);

tree[k].tot=tree[k<<1].tot+query(k<<1|1,mid+1,r,tree[k<<1].maxn);

}}seg;

int n,m;

templateinline void read(nt& x)

int main()

}

洛谷P4198 樓房重建

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

洛谷 P4198 樓房重建

區間最大可修改上公升 線段樹做法,可以分塊亂搞 這道題只是詢問1到n區間,其實可以改成任意區間的最大上公升。首先注意題目是連線,因此不是高度上公升是斜率上公升 y x 但在之後的說明中都會說斜率為高度,大家把他想象成在樓底向上仰望看到多少棟樓。然後造樹,維護h,區間內最大的高度維護 s,區間內的最大...

洛谷P4198 樓房重建 分塊

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