意思就是給你n個數,q次操作,每次改乙個值,或者詢問區間[l,r]內最大的連續子段和。
線段樹維護四個東西,區間和,區間最大子段和,緊靠區間左端點的最大子段和,緊靠區間右端點的最大子段和。
sum,lmax.rmax,dat,分別表示上述四種東西。
sum不用說吧。
對於lmax[k],因為緊靠區間左端點,那麼他的取值要麼來自於左兒子,要麼取左兒子這一段區間內的所有數,以及右兒子的lmax吧:
rmax也是同理。
再看區間最大子段和dat,將區間一切為二,[l,i],[i+1,r],要麼他取[l,i]的dat,要麼取[i+1,r]的dat,要麼兩個區間都取一部分東西和起來,即緊靠i的rmax與緊靠i+1的lmax加起來。
#include#include#include#include#include#include#includeusing namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int maxn=5e5+7;
struct treetree[maxn<<2|1];
void pushup(int k)
void build(int l,int r,int k)
int mid=(l+r)>>1;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
pushup(k);
}void update(int id,int v,int l,int r,int k)
int mid=(l+r)>>1;
if(id<=mid) update(id,v,l,mid,k<<1);
else update(id,v,mid+1,r,k<<1|1);
pushup(k);
}tree myfind(int l,int r,int k,int l,int r)
int mid=(l+r)>>1;
tree f1,f2,ok;
ok.sum=0;
if(l<=mid)
if(r>mid)
//[l,r]區間被切成了兩部分,那麼就需要將他們彙總一下。
if(l<=mid&&r>mid)
return ok;
}int main()
else
}return 0;
}
SGT 線段樹維護區間最大子段和
藍書p208 若將一區間分為兩部分,則必有最大子段存在於左區間 右區間 跨越中間 因此當前節點記錄該段的最大字首和,最大字尾和,段和,區間內最大子段和 now.sum ls.sum rs.sum now.lmax max ls.lmax,ls.sum rs.lmax now.rmax max rs....
線段樹維護最大子段和
查詢的時候返回一整個線段樹節點,而不是乙個值,這樣才有足夠的資訊去處理問題。因為最大子段和如果跨過一些節點,那麼這個最大子段和的資訊本身不一定可以被每個節點所代表的區間的最大子段和表示,所以需要合併一些節點的資訊。include using namespace std const int maxn ...
線段樹維護區間最大子段和 列舉 HDU6638
題意 在乙個二維座標系上給你n n 2000 個點,點帶有乙個價值w 有正有負 點的座標都在 1e9,1e9 的範圍之間,可任意用乙個平行於座標軸的矩形框住一片區域,求這片區域框住的點的價值和 分析 點的座標範圍太大,離散化應能想到。離散化後可以考慮列舉左邊界,列舉左邊界後按照橫座標的依次加點 以一...