codeVS 動態最大子段和

2022-03-03 17:03:04 字數 1265 閱讀 4979

對於最大子段和,我們只需要維護四個變數——maxl,maxr,maxs,sum(分別表示區間最大字首子段和,區間最大字尾子段和,區間最大子段和,區間所有數的和)

然後合併的時候是這樣的:

t[x].sum=t[ls(x)].sum+t[rs(x)].sum;

t[x].maxs=max(max(t[ls(x)].maxs,t[rs(x)].maxs),t[ls(x)].maxr+t[rs(x)].maxl);

t[x].maxl=max(t[ls(x)].maxl,t[ls(x)].sum+t[rs(x)].maxl);

t[x].maxr=max(t[rs(x)].maxr,t[ls(x)].maxr+t[rs(x)].sum);

然後想要強調的是,詢問的時候一定不能像普通線段樹那樣寫,因為我們需要考慮三種情況。一種是該節點表示區間的答案應該從左子節點表示區間取得,一種是該節點表示區間的答案是應該從右子節點表示區間取得,一種是該節點表示區間的答案應該從左右節點中合併取得。

**如下:

#include#include#include#include#include#define maxn 2000010

using namespace std;

int n,m;

long long a[maxn];

struct nodet[maxn<<2];

inline int ls(int x)

inline int rs(int x)

inline void push_up(int x)

inline void build(int x,int l,int r)

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

build(ls(x),l,mid);

build(rs(x),mid+1,r);

push_up(x);

//printf("x=%d l=%d r=%d maxs=%d maxl=%d maxr=%d sum=%d\n",x,l,r,t[x].maxs,t[x].maxl,t[x].maxr,t[x].sum);

}inline node query(int x,int l,int r,int ll,int rr)

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

if(rr<=mid) return query(ls(x),l,mid,ll,rr);

else if(midelse }

int main()

return 0;

}

動態規劃 最大子段和

給定乙個陣列a a0,a1,a2,an 求陣列中 連續子段之和 的最大值。1 最簡單的演算法 窮舉法 計算所有的連續子段之和,得出最大值 窮舉法 計算所有的子串行和 o n 3 public static int maxsum1 int data max tmp max tmp max return...

動態規劃 最大子段和

題目描述 給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入輸出格式 輸入格式 第一行是乙個正整數nn,表示了序列的長度。第二行包含n個絕對值不大於10000的整數a i,描述了這段序列。輸出格式 乙個整數,為最大的子段和是多少。子段的最小長度為1。輸入輸出樣例 輸入樣例 1 72 4 3 ...

動態規劃 最大子段和

動態規劃 最大子段和 lyk喜歡幹一些有挑戰的事,比如說求區間最大子段和。它知道這個題目有o n 的做法。於是它想加強一下。也就是說,lyk一開始有n個數,第i個數字是ai,它找來了乙個新的數字p,並想將這n個數字中恰好乙個數字替換成p。要求替換後的最大子段和盡可能大。lyk知道這個題目仍然很簡單,...