標籤 : 線段樹
給定乙個區間,兩種操作:
操作1:查詢區間內最大子段和
操作2:單點修改。
暴力查詢區間最大子段和時間複雜度是 $ o(n) $ 的,一定會**。觀察資料範圍,正解的時間複雜度大約是 \(log\) 級別的。再根據單點修改,可以嘗試一下線段樹。
單點修改好做,關鍵在於區間查詢最大子段和。主要工作在於線段樹的合併。
我們每個節點維護四個值,乙個是最大字首和,乙個是最大字尾和,乙個是區間和,乙個是區間答案。
我們分步考慮每種情況。
1.字首和:兩種情況,一種是左子樹的最大字首和作為該節點的最大字首和,另一種是左子樹的區間和加上右子樹的最大字首和,比較即可。
2.字尾和:和上面的差不多。
3.區間答案:三種情況,一種是左子樹的答案,一種是右子樹的答案,一種是左子樹的最大字尾與右子樹的最大字首的和,三者比較一下。
以上操作就是 \(pushup\) 的內容。
1.查詢的時候也要進行一次類似於pushup的操作。
2.小心輸入的區間 \(l>r\) (bushi.
#include#include#define maxn 1200000
using namespace std;
typedef long long ll;
ll n,m,a[maxn];
struct tree tree[maxn<<4];
void pushup(int i)
void build(ll i,ll l,ll r)
ll mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
pushup(i);
}tree search(ll i,ll l,ll r)
ll mid=(tree[i].l+tree[i].r)>>1;
if(r<=mid) else if(l>mid)else
}void change(ll i,ll pos,ll x)
ll mid=(tree[i].l+tree[i].r)>>1;
if(pos<=mid) change(i<<1,pos,x);
else change(i<<1|1,pos,x);
pushup(i);
}//void check(int i)
int main()
build(1,1,n);
while(m--) else
} return 0;
}
小白逛公園
描述 小新經常陪小白去公園玩,也就是所謂的遛狗啦 在小新家附近有一條 公園路 路的一邊從南到北依次排著n個公園,小白早就看花了眼,自己也不清楚該去哪些公園玩了。一開始,小白就根據公園的風景給每個公園打了分 小新為了省事,每次遛狗的時候都會事先規定乙個範圍,小白只可以選擇第a個和第b個公園之間 包括a...
小白逛公園
小白逛公園 time limit 20000ms memory limit 65536k case time limit 2000ms description 小新經常陪小白去公園玩,也就是所謂的遛狗啦 在小新家附近有一條 公園路 路的一邊從南到北依次排著n個公園,小白早就看花了眼,自己也不清楚該去...
線段樹 小白逛公園
題目描述 小新經常陪小白去公園玩,也就是所謂的遛狗啦 在小新家附近有一條 公園路 路的一邊從南到北依次排著n個公園,小白早就看花了眼,自己也不清楚該去哪些公園玩了。一開始,小白就根據公園的風景給每個公園打了分 小新為了省事,每次遛狗的時候都會事先規定乙個範圍,小白只可以選擇第a個和第b個公園之間 包...