題目描述-->p1115 最大子段和
雖然是乙個普及-的題,但我敲了線段樹qwq
\(lsum[ ]\)代表 該區間左端點開始的最大連續和.
\(rsum[ ]\)代表 該區間右端點開始的最大連續和.
\(ssum[ ]\)代表 區間內最大連續和.
\(sum[ ]\) 代表區間和.
q:已知乙個區間的左右區間的最大連續和,如何合併?
a:這個區間的最大連續和要麼是左子區間的最大連續和,要麼是右子區間的最大連續和.
要麼是左子區間的最大右起子段和+右子區間的最大左起字段和.
code
:\(ssum[o]=max(max(ssum[lson],ssum[rson]),rsum[lson]+lsum[rson])\)
q:如何更新區間最大左起子段和.
a:新區間的最大左起子段和.要麼是其左子區間最大連續和,要麼是其左子區間和+右子區間的左起子段和.
最大右起子段和同理
code
:\(lsum[o]=max(lsum[lson],sum[lson]+lsum[rson])\)
\(rsum[o]=max(rsum[rson],sum[rson]+rsum[lson])\)
更新操作類似單點修改
貼一下** qwq.
#include#define il inline
#define int long long
#define ri register int
#define n 200008
#define ls o<<1
#define rs o<<1|1
using namespace std;
il void in(int &x)
while(s>='0' and s<='9')
x*=f;
}int tr[n<<2],ssum[n<<2],lsum[n<<2],rsum[n<<2],n;
il void up(int o)
il void build(int o,int l,int r)
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
up(o);
}il int query(int o,int l,int r,int x,int y)
main(void )
P1115 最大子段和
給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入格式 輸入檔案maxsum1.in的第一行是乙個正整數n,表示了序列的長度。第2行包含n個絕對值不大於10000的整數a i 描述了這段序列。輸出格式 輸入檔案maxsum1.out僅包括1個整數,為最大的子段和是多少。子段的最小長度為1。輸...
P1115 最大子段和
給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入格式 輸入檔案maxsum1.in的第一行是乙個正整數n,表示了序列的長度。第2行包含n個絕對值不大於10000的整數a i 描述了這段序列。輸出格式 輸入檔案maxsum1.out僅包括1個整數,為最大的子段和是多少。子段的最小長度為1。輸...
P1115 最大子段和
給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入格式 輸入檔案maxsum1.in的第一行是乙個正整數n,表示了序列的長度。第2行包含n個絕對值不大於10000的整數a i 描述了這段序列。輸出格式 輸入檔案maxsum1.out僅包括1個整數,為最大的子段和是多少。子段的最小長度為1。輸...