P4198 樓房重建

2022-06-05 10:06:10 字數 982 閱讀 4692

題意:

\(n\)棟待建的樓房,站在\((0,0)\)點,對於樓房\(i\)來說,如果從原點能看到樓房的樓頂且沒有樓房阻擋,就算能看到該樓房(?,每次對於一座樓房可以增加高度和減小高度,每次修改後問最多能看到多少棟樓房?

題解:線段樹維護區間斜率最大值,以及區間最長上公升子串行(即斜率遞增)的長度,難點在於區間的合併:

對於每次修改:可以log遞迴去合併該區間,那麼每次修改的時間複雜度為\((^2)\)

對於區間合併:

很顯然的一點,就是乙個區間的第乙個元素是一定可以看到的,因為前面沒有任何的房屋阻擋。

1.如果左區間的斜率最大值小於右區間的第乙個值,那麼總區間的最長上公升子串行的長度為左右最長上公升子串行的和。

2.如果左區間的最大值大於右區間最大值,那麼右區間的所有都不能看到。

3.否則遞迴處理該區間的左右子區間,如果左子區間最大值小於剛才的最大值,那麼遞迴處理右區間,否則處理左區間加上右區間的答案。

#include "bits/stdc++.h"

using namespace std;

const int n=1e5+5;

int n,m;

double a[n];

struct nodeb[4*n];

void push(int p)

int pushup(double tmp,int s,int t,int p)

void update(int s,int t,int p,int c,int w)

int mid=(s+t)/2;

if(c<=mid) update(s,mid,p<<1,c,w);

else update(mid+1,t,p<<1|1,c,w);

push(p);

l(p)=l(p<<1)+pushup(m(p<<1),mid+1,t,p<<1|1);

}int main()

return 0;

}

P4198 樓房重建

傳送門 很妙的思路 首先,我們可以把每一棟樓房轉化為它的頂部到原點這條直線的斜率,這樣就變成了從乙個序列中選出乙個最長上公升子串行 其實不是最長上公升子串行,不過可以這麼理解 考慮用線段樹來維護,對於每個區間,我們維護這個區間的最大值以及這個區間的答案,那麼最後的答案就是 ans 1 對於葉節點來說...

P4198 樓房重建(思維)

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

P4198 樓房重建 線段樹

n nn條線,開始時第i ii條是 i,0 i,0 i,0 的乙個點。每次有操作把第x xx條線變成 x,0 x,0 x,0 到 x,y x,y x,y 然後求從 0,0 0,0 0,0 能看到幾條線。把線變成斜率的話就是對於每個點求乙個往後比它大的第乙個點然後一直跳來做了。線段樹的話主要是合併區間...