BZOJ2957 樓房重建 分塊

2022-05-21 17:12:16 字數 1165 閱讀 5477

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

2資料約定

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

n,m<=100000

題解:分塊。易知如果乙個樓房能被看見,當且僅當它的房頂到(0,0)連線的斜率 比前面的都大。我們暴力維護每個塊內斜率的最長上公升序列,然後查詢的時候二分找到塊內第乙個能看到的,那麼它之後的所有最長上公升序列裡的元素就都能被看到,再去搜下乙個塊就好了。

據說把塊的大小改成sqrt(n*log(n)/2)會有奇效?

有沒有奇效我不知道,反正我因為陣列開小wa了無數次

#include #include #include #include #include using namespace std;

const int maxn=110000;

int n,m,siz,ans,pre;

int t[1000],s[1000],h[maxn],p[1000][1000];

bool cmp(int a,int b)

int main()

ans+=p[j][0]+1-r;

if(p[j][0]>=l) pre=p[j][p[j][0]];

} printf("%d\n",ans);

} return 0;

}

BZOJ2957 樓房重建 分塊

貌似是一道線段樹的題,然而線段樹太燒腦想不出來,只能暴力的玩分塊。分塊很好想的,維護 n 個塊,每塊都按照斜率單調遞增的標準來維護。查詢把所有塊for一遍。因為每個塊的斜率都是單調遞增的,對於每個塊使用二分可以節省一點點時間,就可以偷稅 愉悅 的accepted了 玩個斜率就不該用float 就為了...

bzoj 2957 樓房重建 分塊

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

分塊 bzoj2957 樓房重建

orz 分塊大爺。思路很神奇也很清晰。把 塊內最值 和 塊內有序 兩種良好的性質結合起來,非常棒地解決了這個問題。圖中黑色的樓房即為每個塊內的 可視序列 顯而易見,在塊內它們的k 斜率 是單增的。由於上圖中第乙個塊的maxk比後面兩個塊的maxk都要大,所以後兩個塊對答案沒有貢獻,這也是顯然的。這就...