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

2022-05-08 04:06:08 字數 1527 閱讀 3902

q種操作,查詢區間內最長連續上公升子串行的長度,或者修改某個點的值

線段樹維護:區間內最長連續上公升子串行的長度sub、區間內以左端點為起點的最長連續上公升子串行的長度lsub、區間內以右端點為終點的最長連續上公升子串行的長度rsub、區間左端點的值l和右端點的值r。

1

#define io std::ios::sync_with_stdio(0);

2 #include 3

#define iter ::iterator

4using

namespace

std;

5 typedef long

long

ll;6 typedef pairp;

7#define pb push_back

8#define se second

9#define fi first

10#define rs o*2+1

11#define ls o*2

12const ll inf=0x7fffffff;13

const

int n=1e5+5;14

struct

nodea[n*4

];19

void pu(int o,int

len)

26 a[o].lsub=a[ls].lsub;

27if(a[ls].lsub==len-len/2&&a[rs].l>a[ls].r)

30 a[o].rsub=a[rs].rsub;

31if(a[o].rsub==len/2&&a[rs].l>a[ls].r)34}

35void build(int o,int l,int

r)43

int m=(l+r)/2;44

build(ls,l,m);

45 build(rs,m+1

,r);

46 pu(o,r-l+1

);47}48

void up(int o,int l,int r,int p,int

v)53

int m=(l+r)/2;54

if(p<=m)up(ls,l,m,p,v);

55else up(rs,m+1

,r,p,v);

56 pu(o,r-l+1

);57}58

int query(int o,int l,int r,int ql,int

qr)62

int m=(l+r)/2;63

int res=0;64

if(ql<=m)res=max(res,query(ls,l,m,ql,qr));

65if(qr>m)res=max(res,query(rs,m+1

,r,ql,qr));

66if(ql<=m&&qr>m&&a[ls].r69return

res;70}

71int

t,n,q;

72int

main()87}

88}89 }

HDU 3308 LCIS(線段樹合併)

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

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

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

HDU 3308 LCIS 線段樹 區間合併

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