BZOJ2957 樓房重建

2021-07-30 12:08:47 字數 1836 閱讀 7548

description

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

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

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

input

第一行兩個正整數n,m

接下來m行,每行兩個正整數xi,yi

output

m行,第i行乙個整數表示第i天過後小a能看到的樓房有多少棟

sample input

3 4

2 43 6

1 1000000000

1 1

sample output
111

2

hint

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

題解

根據題意,要求出區間內單調上公升的斜率個數。

現在的問題就算怎麼合併兩個答案區間。

我們可以發現

1.對於左區間l與右區間r,如果l最大的斜率比r大,那麼r的所有樓房都會被擋住。所以答案就算l區間的答案。

2.否則,如果r的左區間最大斜率比l的最大還要小,那麼只有r的右區間可能有答案,就遞迴尋找r的右區間的答案。

3.如果r的左區間最大斜率比l的最大還要大,那麼r的右區間的所有都符合答案,但注意不是直接用r的右區間的答案,而是用r的答案-r的左區間的答案,再遞迴尋找r的左區間的答案。

所以,這道題就要維護乙個區間答案與區間最大值,不用懶惰標記。

本入**奇醜無比,不喜勿噴

#include 

#include

#include

#include

#include

#include

#include

#define maxn 100000+10

#define ll long long

using

namespace

std;

int ans[maxn<<2],l[maxn<<2],r[maxn<<2],a,b,n,m;

double mx[maxn<<2];

int cal(int rt,double v)

void pushup(int rt)

void build(int rt,int l,int r)

void update(int x,double c,int l,int r,int rt)

int m=(l+r)>>1;

if(x<=m) update(x,c,l,m,rt<<1);

else

if(x>m) update(x,c,m+1,r,rt<<1|1);

pushup(rt);

}int main()

return

0;}

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了,只能說考試時候資料水了。這題有兩種做法,一種...