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 42 4
3 61 1000000000
1 1sample output
資料約定
對於所有的資料1<=xi<=n,1<=yi<=10^9,n,m<=100000
我們建一棵線段樹維護每個點的斜率,也就是說只有斜率嚴格大於左邊的點才能統計進入答案。用乙個陣列儲存每個結點的答案,記為t,另乙個陣列儲存結點中所有斜率的最大值,記為tmax。對於每次統計,顯然t[i]是包括了t[i<<1]的,而右邊部分我們考慮分類討論,首先把右邊分成兩塊,記為u,v。如果u的最大值要小於左邊(tmax[i<<1]),那麼u這一塊的所有樓房肯定都是對答案沒有貢獻的,直接遞迴統計v部分。而如果u的最大值大於tmax[i<<1],則答案為左邊部分的答案加上t[i<<1|1]-t[u] (這是v部分的答案,因為此時的這些答案肯定都是大於tmax[u]的,那麼顯然也大於現在check的這個值。)之後我們就只需要單點修改與區間統計了,其實也就是用線段樹求lis。
#include
#include
#include
using
namespace
std;
const
int maxx = 100000 + 50;
int t[maxx<<2];
double tmax[maxx<<2];
int n,m;
double x,y;
int chk(int i,int l,int r,double pos)
void modify(int i,int l,int r,int pos,double k)
int mid = (l+r) >> 1;
if(pos <= mid) modify(i<<1,l,mid,pos,k);
if(pos > mid) modify(i<<1|1,mid+1,r,pos,k);
tmax[i] = max(tmax[i<<1],tmax[i<<1|1]);
t[i] = t[i<<1] + chk(i<<1|1,mid+1,r,tmax[i<<1]);
}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了,只能說考試時候資料水了。這題有兩種做法,一種...