BZOJ2957 樓房重建

2022-03-03 16:13:15 字數 1038 閱讀 8122

對於乙個區間,我們記錄兩個引數——\(ans\)表示這個區間裡面的上公升子串行的個數,\(k\)表示最大的斜率。

關鍵是怎麼合併?肯定是左區間的ans+右區間在左區間最大斜率的限制下的上公升子串行個數。

怎麼計算右區間的那一部分?我們把右區間分成左子區間和右子區間。如果左子區間的最大斜率比當前限制斜率(即左區間最大斜率)大,右子區間相當於限制和原先一樣,只要遞迴計算左子區間,再加上右子區間原本的貢獻即可。(注意不是右子區間的sum,因為那個沒有大於左邊的限制,具體寫法請見**)。如果左子區間的最大斜率比限制斜率小,那左子區間就相當於全部都看不到了,所以遞迴計算右子區間即可qwqwq

**如下:

#include#include#include#include#includeusing namespace std;

#define maxn 100010

int n,m;

struct nodet[maxn<<2];

inline int ls(int x)

inline int rs(int x)

inline void build(int x,int l,int r)

inline int calc(int x,double k)

if(t[ls(x)].maxx<=k) return calc(rs(x),k);

else return calc(ls(x),k)+t[x].sum-t[ls(x)].sum;

}inline void update(int x,int pos,double k)

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

if(pos<=mid) update(ls(x),pos,k);

else update(rs(x),pos,k);

t[x].maxx=max(t[ls(x)].maxx,t[rs(x)].maxx);

t[x].sum=t[ls(x)].sum+calc(rs(x),t[ls(x)].maxx);

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