BZOJ2957 樓房重建 線段樹,遞迴

2022-04-30 09:18:10 字數 780 閱讀 1366

經典的一道線段樹題,難點在於如何合併節點.

由於題目要求直線要求不相交,則斜率均大於前面的點即為答案.

所以以斜率為權值.

考慮線段樹每乙個節點維護兩個值:

每一次插入乙個節點,它僅會對沿途的最大值和答案產生影響.

然後每次將已經統計好左兒子的 \(max\) 加入與右兒子中的答案進行比較,遞迴完成整棵線段樹.

然後詳情可以看**.

#include#define n 100008

using namespace std;

struct nodesgm[n*4];

int n,m,x,k;

int calc(int node,double maxn,int l,int r)

void update(int node,int l,int r,int x,double k)

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

if (x<=mid) update(node<<1,l,mid,x,k);

else update(node<<1|1,mid+1,r,x,k);

sgm[node].max=max(sgm[node<<1].max,sgm[node<<1|1].max);

sgm[node].sum=sgm[node<<1].sum+calc(node<<1|1,sgm[node<<1].max,mid+1,r);

//左邊已經處理完,逐層遞迴返回

}int main()

}

BZOJ2957 樓房重建(線段樹)

這裡放傳送門 可以發現如果一段樓房能被看見,那麼它們跟原點的連線的斜率都是單調遞增的。於是這就變成了乙個維護上公升序列的題。這裡的上公升序列不是最長上公升子串行那樣的東西,而是相當於貪心地選擇,選中的子串行中的每乙個元素它前面都不能存在大於等於它的元素。比如說,有乙個斜率序列是1,2,4,3,4,如...

BZOJ2957 樓房重建 線段樹

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

bzoj2957樓房重建 線段樹

小a的樓房外有一大片施工工地,工地上有n棟待建的樓房。每天,這片工地上的房子拆了又建 建了又拆。他經常無聊地看著窗外發呆,數自己能夠看到多少棟房子。為了簡化問題,我們考慮這些事件發生在乙個二維平面上。小a在平面上 0,0 點的位置,第i棟樓房可以用一條連線 i,0 和 i,hi 的線段表示,其中hi...