BZOJ2957 樓房重建 線段樹

2022-02-27 20:28:29 字數 2008 閱讀 2415

小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 4

3 61 1000000000

1 1資料約定

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

n,m<=100000

線段樹還能這樣玩。。學到了

首先求出每個樓到原點的斜率,題目實質就轉化為了維護最長上公升子串行

乙個很自然的想法就是開乙個線段樹記錄區間最大值mx和區間答案ans

如果左區間mx>右區間mx,直接返回左區間答案

如果左區間mx<=右區間mx,就有點棘手

可以對右區間遞迴處理,將右區間再分為兩個子區間【其實就是線段樹上的】

①若區間長度為1,直接判斷

②若左區間mx比當前最大值小,對右區間遞迴處理

③若左區間mx較大,在整個區間中右區間的答案不受影響,將整個區間的答案減去左區間的答案再加上左區間遞迴處理的答案即可

複雜度o(n

log2

n)

#include

#include

#include

#include

#include

#include

#define ll long long int

#define rep(i,n) for (int i = 1; i <= (n); i++)

#define redge(u) for (int k = h[u],to; k; k = ed[k].nxt)

#define bug(s,n) for (int i = 1; i <= (n); i++) cout<#define ls (u << 1)

#define rs (u << 1 | 1)

#define eps 1e-9

using namespace std;

const

int maxn = 100005,maxm = 100005,inf = 1000000000;

inline int rd()

while (c >= 48 && c <= 57)

return

out * flag;

}int n,m,ans[4 * maxn],l[4 * maxn],r[4 * maxn];

double mx[4 * maxn];

int cal(int u,double h)

void modify(int u,int l,int r,int pos,double v)

int mid = l + r >> 1;

if (mid >= pos) modify(ls,l,mid,pos,v);

else modify(rs,mid + 1,r,pos,v);

if (mx[ls] > mx[rs]) mx[u] = mx[ls],ans[u] = ans[ls];

else mx[u] = mx[rs],ans[u] = ans[ls] + cal(rs,mx[ls]);

}void build(int u,int l,int r)

int main()

return

0;}

BZOJ2957 樓房重建(線段樹)

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

BZOJ2957 樓房重建 線段樹

題目 time limit 10 sec memory limit 256 mb submit 2259 solved 1069 submit status discuss 小a的樓房外有一大片施工工地,工地上有n棟待建的樓房。每天,這片工地上的房子拆了又建 建了又拆。他經常無聊地看著窗外發呆,數自...

bzoj2957樓房重建 線段樹

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