P4198 樓房重建(線段樹,維護LIS)

2021-10-08 05:21:44 字數 1728 閱讀 5846

思路:

實際上是在維護兩個值:區間最值mxmx

mx和區間最長上公升子串行len

lenle

n。只不過這裡的最長上公升子串行有限制:要求能取盡量取,也就1 5 2 3 4的len

lenle

n是2不是4。

想清楚了要維護的值,我們就要想怎麼維護。

對於l en

lenle

n值,我們只需要對pus

huppushup

pushup

進行修改。

int

pushup2

(int i,

double mx)

左右區間的len

lenle

n值我們已經算好了,合併起來則和mxmx

mx值有關係

如果當前區間的mxmx

mx值小於之前的mxmx

mx值,則所以len

lenle

n值都統計不上了。

如果當前左區間的mxmx

mx值大於之前的mxmx

mx值,說明右區間的len

lenle

n值一定由大於mxmx

mx的部分貢獻而來,所以可以直接統計,然後再統計左區間部分。

#include

#include

#include

#include

#include

using

namespace std;

const

int maxn =

1e5+7;

struct tree t[maxn <<2]

;void

pushup1

(int i)

intpushup2

(int i,

double mx)

void

build

(int i,

int l,

int r)

int m =

(t[i]

.l + t[i]

.r)>>1;

build

(i *

2,l,m)

;build

(i *2+

1,m +

1,r)

;pushup1

(i);

}void

update

(int i,

int x,

int v)

int m =

(t[i]

.l + t[i]

.r)>>1;

if(x <= m)

update

(i *

2,x,v);if

(x > m)

update

(i *2+

1,x,v)

;pushup1

(i);

t[i]

.len = t[i *2]

.len +

pushup2

(i *2+

1,t[i *2]

.mx);}

intmain()

return0;

}

P4198 樓房重建 線段樹

n nn條線,開始時第i ii條是 i,0 i,0 i,0 的乙個點。每次有操作把第x xx條線變成 x,0 x,0 x,0 到 x,y x,y x,y 然後求從 0,0 0,0 0,0 能看到幾條線。把線變成斜率的話就是對於每個點求乙個往後比它大的第乙個點然後一直跳來做了。線段樹的話主要是合併區間...

P4198 樓房重建

傳送門 很妙的思路 首先,我們可以把每一棟樓房轉化為它的頂部到原點這條直線的斜率,這樣就變成了從乙個序列中選出乙個最長上公升子串行 其實不是最長上公升子串行,不過可以這麼理解 考慮用線段樹來維護,對於每個區間,我們維護這個區間的最大值以及這個區間的答案,那麼最後的答案就是 ans 1 對於葉節點來說...

P4198 樓房重建

題意 n 棟待建的樓房,站在 0,0 點,對於樓房 i 來說,如果從原點能看到樓房的樓頂且沒有樓房阻擋,就算能看到該樓房 每次對於一座樓房可以增加高度和減小高度,每次修改後問最多能看到多少棟樓房?題解 線段樹維護區間斜率最大值,以及區間最長上公升子串行 即斜率遞增 的長度,難點在於區間的合併 對於每...