洛谷P4198 樓房重建 分塊

2022-04-30 07:27:08 字數 1883 閱讀 6778

小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能看到的樓房有多少棟

輸入樣例#1:

3 42 4

3 61 1000000000

1 1輸出樣例#1:11

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

n,m<=100000

我們發現能看見的樓房的個數,就是這些樓房的斜率的最長上公升子串行的長度,可以線段樹維護,也可以分塊,但是分塊要慢得多

博主在這裡講一下分塊的做法,線段樹以後再補?

設有兩個點a,b,高度分別為h[a],h[b],如果a不會被b阻擋,必有\(\frac>=\frac\),化為乘法形式為\(h[a]\times b>=h[b]\times a\),特別的,對於原點,我們特判一下,h[a]是不是大於0就可以了

對於修改,我們暴力更新本塊內元素資訊,每次清零,重新維護乙個塊內最長上公升子串行的長度,時間複雜度\(o(\sqrt n)\)

對於查詢,設last為上乙個滿足條件的塊的末尾節點,我們每次從塊1開始,一直到最後一塊,在塊內二分查詢(因為是最長上公升子串行,所以滿足單調性)與last相比剛剛滿足條件的點,那麼從這個點開始一直到塊末都是合法的序列,把答案加上這一段區間的長度,然後把last更新為本塊末尾,繼續上述操作

時間複雜度\(o(\sqrt n)\)

然而這樣是會t的,我們把塊的大小改為\(\sqrt }\)會有奇效,但是記得陣列大小也要相應更改

#include#define rg register

#define lol long long

#define il extern inline

#define min(a,b) (a)<(b)?(a):(b)

#define max(a,b) (a)>(b)?(a):(b)

#define in(i) (i=read())

using namespace std;

const lol n=1e5+10;

int read()

while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar();

return ans*f;

}int n,m,blo,h[n],pos[n];

struct stack t[330];

il bool check(lol a,lol b)

void print(int x)

int main()

if(aq) last=t[i].s[t[i].top],ans+=t[i].top-aq+1;

}print(ans),putchar('\n');

}}

洛谷P4198 樓房重建

題意 給定序列,每次修改乙個值,求字首最大值的個數。解 線段樹經典應用。每個節點維護最大值和該區間字首最大值個數。發現我們不用下傳標記,只需要合併區間。需要實現乙個函式int ask l r lm 求出區間 l r 中前乙個數是lm時字首最大值個數。那麼當lm large ls 時,return a...

洛谷 P4198 樓房重建

區間最大可修改上公升 線段樹做法,可以分塊亂搞 這道題只是詢問1到n區間,其實可以改成任意區間的最大上公升。首先注意題目是連線,因此不是高度上公升是斜率上公升 y x 但在之後的說明中都會說斜率為高度,大家把他想象成在樓底向上仰望看到多少棟樓。然後造樹,維護h,區間內最大的高度維護 s,區間內的最大...

洛谷 P4198 樓房重建 題解

題面 首先你要知道題問的是什麼 使用一種資料結構,動態地維護以1為起點地最長上公升子串行 把樓房的高度轉化成斜率地序列 的長度 怎麼做?線段樹!初始化 對於每乙個葉子節點,從這段區間頭可以看到的樓房數量一定為1,區間斜率最大值一定為該點的斜率 在合併時 1.我們可以先查詢右區間的左區間的最大值,如果...