題面
首先你要知道題問的是什麼:
使用一種資料結構,動態地維護以1為起點地最長上公升子串行(把樓房的高度轉化成斜率地序列)的長度;
怎麼做?線段樹!
初始化:
對於每乙個葉子節點,從這段區間頭可以看到的樓房數量一定為1,區間斜率最大值一定為該點的斜率;
在合併時:
1.我們可以先查詢右區間的左區間的最大值,如果右區間的左區間的最大值
比左區間的最大值小,那麼右區間的左區間
的所有答案一定看不到,所以我們就可以遞迴查詢右區間的右區間
2.如果右區間的左區間的最大值比左區間的最大值大,那麼原來被右區間的左區間擋住的現在一樣會被擋住,我們就可以加上右區間的右區間的答案,所以我們可以遞迴查詢右區間的左區間
時間複雜度是o(nlog^2n);
#include #define inc(i,a,b) for(register int i=a;i<=b;i++)using namespace std;
class segmenttree[2000010];
int query(int k,int l,int r,double goal)
if(l==r)
int mid=(l+r)/2;
if(tree[k<<1].maxn<=goal)
else
} void change(int k,int l,int r,int goal,double value)
int mid=(l+r)/2;
if(goal<=mid) change(k<<1,l,mid,goal,value);
else change(k<<1|1,mid+1,r,goal,value);
tree[k].maxn=max(tree[k<<1].maxn,tree[k<<1|1].maxn);
tree[k].tot=tree[k<<1].tot+query(k<<1|1,mid+1,r,tree[k<<1].maxn);
}}seg;
int n,m;
templateinline void read(nt& x)
int main()
}
洛谷P4198 樓房重建
題意 給定序列,每次修改乙個值,求字首最大值的個數。解 線段樹經典應用。每個節點維護最大值和該區間字首最大值個數。發現我們不用下傳標記,只需要合併區間。需要實現乙個函式int ask l r lm 求出區間 l r 中前乙個數是lm時字首最大值個數。那麼當lm large ls 時,return a...
洛谷 P4198 樓房重建
區間最大可修改上公升 線段樹做法,可以分塊亂搞 這道題只是詢問1到n區間,其實可以改成任意區間的最大上公升。首先注意題目是連線,因此不是高度上公升是斜率上公升 y x 但在之後的說明中都會說斜率為高度,大家把他想象成在樓底向上仰望看到多少棟樓。然後造樹,維護h,區間內最大的高度維護 s,區間內的最大...
洛谷P4198 樓房重建 分塊
小a的樓房外有一大片施工工地,工地上有n棟待建的樓房。每天,這片工地上的房子拆了又建 建了又拆。他經常無聊地看著窗外發呆,數自己能夠看到多少棟房子。為了簡化問題,我們考慮這些事件發生在乙個二維平面上。小a在平面上 0,0 點的位置,第i棟樓房可以用一條連線 i,0 和 i,hi 的線段表示,其中hi...