HDU 3308 LCIS 線段樹,連續遞增子

2021-06-08 20:19:23 字數 1404 閱讀 3943

by---cxlove

題目:給出乙個序列,兩種操作,單點更新值,以及查詢區間的最長連續遞增子串行長度

這題比較簡單,如果是求最長遞增子串行長度就難了,不需要連續就是簡單的區間合併類的線段樹了。

每乙個結點要記錄包含左端點的最長連續遞增子長度,包含右端點的最長連續遞增子長度,以及整個區間的最長遞增子長度,典型的區間合併問題。

向上更新部分要注意細節

對於左連續的話,可以由左孩子的左連續得來,但是可能包括右孩子的左連續,要進行判斷左孩子的左連續是否是整個區間,而且中間的結合是否滿足遞增

右連續一樣。

對於整個區間的最值,可能**與左右孩子的最值,也可以**於兩個區間的中間部分。

更新部分不需要解釋,直接更新到葉子節點,然後通過子節點更新父節點

查詢的時候有點麻煩,需要區間合併的時候需要格外注意

左右孩子分別找的結果,以及可能是 兩個區間的合併,但是要注意細節

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define ll long long

#define eps 1e-7

#define zero(a) fabs(a)a[l[lson].right])?l[rson].lx:0);

l[step].rx=l[rson].rx+((l[rson].rx==l[rson].dist()&&a[l[rson].left]>a[l[lson].right])?l[lson].rx:0);

l[step].mx=max(max(l[lson].mx,l[rson].mx),a[l[rson].left]>a[l[lson].right]?(l[lson].rx+l[rson].lx):0);

}void bulid(int step,int l,int r)

bulid(lson,l,l[step].mid);

bulid(rson,l[step].mid+1,r);

push_up(step);

}void update(int step,int pos,int k)

if(pos<=l[step].mid) update(lson,pos,k);

else update(rson,pos,k);

push_up(step);

}int query(int step,int l,int r)

}int main(){

int t,n,m,l,r;

char str[10];

scanf("%d",&t);

while(t--){

scanf("%d%d",&n,&m);

for(int i=0;i

HDU 3308 LCIS(線段樹合併)

維護乙個區間的包含最左的元素的lcis,包含最右元素的lcis,以及整個區間的lcis,然後pushup的時候就更新這三個值就行了。注意要考慮左右兒子可以 接 起來的情況等等 查詢的時候要注意,也要考慮左右可以 接 起來時候,不過還要注意,有可能左右兒子邊界的已經 越界了 就是超過了查詢範圍,還要取...

HDU 3308 LCIS(線段樹區間合併)

給你乙個序列,現在進行一些操作,一種是詢問某一段最長連續上公升子串行 lcis 的長度,另乙個就是修改某個點的值 區間合併的簡單題 這裡的區間合併,要判斷的是左兒子最右邊的值和右兒子最左邊的值的關係,那麼我們這道題要維護的東西就有 最左端開始的lcis,包括最右端的lcis,該區間的lcis,最左邊...

HDU 3308 LCIS 線段樹 區間合併

題目鏈結 前言 最近在做線段樹的練習,對於區間合併問題不是很清楚,花了好久才把線段樹的區間合併問題理清楚,所以把學習的過程記錄下來,建議手動建樹並模擬測試用例 題目大意 有乙個陣列,求這個陣列中最長的單調連續遞增序列的長度 題解 見一下注釋 樹結點的定義 有該結點的左端點 右端點 有該結點對應區間的...