題意: 維護資料結構,支援區間賦值,查詢區間最大欄位和
我們乙個點存4個值
l_max 表示從左端點開始的最大欄位和
r_max 表示從右端點開始的最大欄位和
max 表示區間的最大欄位和
val 表示區間和
考慮如何更新
我們發現對於任何乙個節點的max, 要麼全取右子樹,要麼全取左子樹,要麼乙個取一點
l_max 要麼還是取右子樹,要麼取右子樹全部,再加上左子樹的l_max
r_max 同理
void pushup(int x)
查詢也同理
void quary(int o,int l,int r,int &ans,int &lans,int &rans)
int mid=(t[o].r+t[o].l)>>1;
if(r<=mid) quary(o<<1,l,r,ans,lans,rans);//全左
else if(l>mid) quary(o<<1|1,l,r,ans,lans,rans);//全右
else
}
區間賦值打tag就可以了
//區間賦值,區間最大欄位和
#include#define n 100005
#define len (t[o].r-t[o].l+1)
#define llen (t[o<<1].r-t[o<<1].l+1)
#define rlen (t[o<<1|1].r-t[o<<1|1].l+1)
using namespace std;
struct nodet[n<<2];
int n,m,a[n],ans,la,ra;
int read()
while(isdigit(ch))cnt=cnt*10+(ch-'0'),ch=getchar();
return cnt*f;
}void pushup(int x)
void pushdown(int o)
else
t[o<<1].val = t[o].tag * llen; t[o<<1].tag+=t[o].tag;
t[o<<1|1].val = t[o].tag * rlen; t[o<<1|1].tag+=t[o].tag;
t[o].tag=0; }}
void build(int o,int l,int r)
int mid=(l+r)>>1;
build(o<<1,l,mid),build(o<<1|1,mid+1,r);
pushup(o);
}void update(int o,int l,int r,int val)
pushdown(o);
int mid=(t[o].l+t[o].r)>>1;
if(l<=mid) update(o<<1,l,r,val);
if(r>mid) update(o<<1|1,l,r,val);
pushup(o);
}void quary(int o,int l,int r,int &ans,int &lans,int &rans)
int mid=(t[o].r+t[o].l)>>1;
if(r<=mid) quary(o<<1,l,r,ans,lans,rans);
else if(l>mid) quary(o<<1|1,l,r,ans,lans,rans);
else
}int main()
else
} }
最大欄位和
include include include include include using namespace std 最大欄位和問題描述 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0,...
最大欄位和
1049 最大子段和 難度 基礎題 n個整數組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的連續子段和的最大值。當所給的整數均為負數時和為0。例如 2,11,4,13,5,2,和最大的子段為 11,4,13。和為20。input 第1行 整數序列的長度n 2 n 5...
最大欄位和
題目描述 給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入格式 第一行 是乙個正整數n,表示了序列的長度。第二行 包含n個整數num i 描述了這段序列。輸出格式 第一行 乙個整數,為最大的子段和是多少。第二行 起始位置和終止位置 輸入樣例 72 4 3 1 2 4 3 輸出樣例 43 5...