線段樹維護最大欄位和

2021-08-28 21:00:11 字數 1809 閱讀 3443

題意: 維護資料結構,支援區間賦值,查詢區間最大欄位和

我們乙個點存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...