題解 小白逛公園

2022-09-09 19:21:23 字數 1422 閱讀 7220

標籤 : 線段樹

給定乙個區間,兩種操作:

操作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個公園之間 包...