對於最大子段和,我們只需要維護四個變數——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知道這個題目仍然很簡單,...