P4513 小白逛公園 線段樹

2022-04-30 09:42:08 字數 1227 閱讀 2374

線段樹是一門比較刁鑽的手藝...

此題我們需要維護 \(4\) 個變數:

\(amx\) 代表當前節點的最大值.

\(lmx\) 代表當前節點以左端點為起點的區間最大值.

\(rmx\) 代表當前節點以右端點為結尾的區間最大值.

\(sum\) 代表整段的和.

然後我們在 \(push\)_\(up\) 的時候,也是要做蠻多工作.

\(lc\) 為左端點,\(rc\) 為右端點.

\(lmx=max(lmx_,sum_+lmx_)\)

也就是說可以單獨取左兒子裡的最大值,也可以一直取到右兒子的 \(lmx\) 為止.

\(rmx=max(rmx_,sum_+rmx_)\)

和上文同理.

\(sum=sum_+sum_\)

\(amx=max(amx_,amx_,rmx_+lmx_)\)

最關鍵的一步,更新每乙個節點的答案. 可以在圖上自己理解,此處不贅述.

特別注意,查詢的時候也要把所有查出來的區間進行類似的操作...

#includeusing namespace std;

const int maxn=1000008;

struct node

sgm[maxn*4];

int n,m,k,x,y;

int cnt,a[maxn];

void push_up(int x)

void build(int l,int r,int now)

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

sgm[now].lc=2*now;

build(l,mid,sgm[now].lc);

sgm[now].rc=2*now+1;

build(mid+1,r,sgm[now].rc);

push_up(now);

}void change(int now,int to,int num)

int mid=(x+y)>>1;

if(to<=mid) change(sgm[now].lc,to,num);

else change(sgm[now].rc,to,num);

push_up(now);

}node query(int now,int l,int r)

}int main()

else change(1,x,y);

}return 0;

}

P4513 小白逛公園 線段樹

小新經常陪小白去公園玩,也就是所謂的遛狗啦 在小新家附近有一條 公園路 路的一邊從南到北依次排著nn個公園,小白早就看花了眼,自己也不清楚該去哪些公園玩了。一開始,小白就根據公園的風景給每個公園打了分 小新為了省事,每次遛狗的時候都會事先規定乙個範圍,小白只可以選擇第aa個和第bb個公園之間 包括a...

P4513 小白逛公園

小新經常陪小白去公園玩,也就是所謂的遛狗啦 在小新家附近有一條 公園路 路的一邊從南到北依次排著n nn個公園,小白早就看花了眼,自己也不清楚該去哪些公園玩了。一開始,小白就根據公園的風景給每個公園打了分 小新為了省事,每次遛狗的時候都會事先規定乙個範圍,小白只可以選擇第a aa個和第b bb個公園...

題解 洛谷P4513 小白逛公園(線段樹)

這裡要對某個葉子節點的值進行修改,最後求某一段區間內的某一段和的最大值,可以用線段樹來解決,但需要多開一些陣列儲存更多的資訊。我們定義ln陣列記錄某個結點從左開始某一段區間和的最大值,定義rn陣列為某個結點從右開始某一段區間和的最大值,定義midd陣列記錄某個結點在中間的某一段區間和的最大值,sum...