hihocoder 1078 線段樹的區間修改 (線段樹 區間更新 模板)
描述
對於小Ho表現出的對線段樹的理解,小Hi表示挺滿意的,但是滿意就夠了麼?於是小Hi將問題改了改,又出給了小Ho:
假設貨架上從左到右擺放了N種商品,並且依次標號為1到N,其中標號為i的商品的價格為Pi。小Hi的每次操作分為兩種可能,第一種是修改價格——小Hi給出一段區間[L, R]和一個新的價格NewP,所有標號在這段區間中的商品的價格都變成NewP。第二種操作是詢問——小Hi給出一段區間[L, R],而小Ho要做的便是計算出所有標號在這段區間中的商品的總價格,然後告訴小Hi。
那麼這樣的一個問題,小Ho該如何解決呢?
輸入
每個測試點(輸入檔案)有且僅有一組測試資料。
每組測試資料的第1行為一個整數N,意義如前文所述。
每組測試資料的第2行為N個整數,分別描述每種商品的重量,其中第i個整數表示標號為i的商品的重量Pi。
每組測試資料的第3行為一個整數Q,表示小Hi進行的運算元。
每組測試資料的第N+4~N+Q+3行,每行分別描述一次操作,每行的開頭均為一個屬於0或1的數字,分別表示該行描述一個詢問和一次商品的價格的更改兩種情況。對於第N+i+3行,如果該行描述一個詢問,則接下來為兩個整數Li, Ri,表示小Hi詢問的一個區間[Li, Ri];如果該行描述一次商品的價格的更改,則接下來為三個整數Li,Ri,NewP,表示標號在區間[Li, Ri]的商品的價格全部修改為NewP。
對於100%的資料,滿足N<=10^5,Q<=10^5, 1<=Li<=Ri<=N,1<=Pi<=N, 0<Pi, NewP<=10^4。
輸出
對於每組測試資料,對於每個小Hi的詢問,按照在輸入中出現的順序,各輸出一行,表示查詢的結果:標號在區間[Li, Ri]中的所有商品的價格之和。
10
4733 6570 8363 7391 4511 1433 2281 187 5166 378
6
1 5 10 1577
1 1 7 3649
0 8 10
0 1 4
1 6 8 157
1 3 4 1557
樣例輸出
4731
14596
題目連結:http://hihocoder.com/problemset/problem/1078
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std;
int const MAX = 1e5 + 5;
int sum[MAX << 2], lazy[MAX << 2];
void PushUp(int rt)
{
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void PushDown(int rt, int ln, int rn)
{
if(lazy[rt])
{
sum[rt << 1] = ln * lazy[rt];
sum[rt << 1 | 1] = rn * lazy[rt];
lazy[rt << 1] = lazy[rt];
lazy[rt << 1 | 1] = lazy[rt];
lazy[rt] = 0;
}
return;
}
void Build(int l, int r, int rt)
{
lazy[rt] = 0;
if(l == r)
{
scanf("%d", &sum[rt]);
return;
}
int mid = (l + r) >> 1;
Build(lson);
Build(rson);
PushUp(rt);
return;
}
void Update(int L, int R, int val, int l, int r, int rt)
{
if(L <= l && r <= R)
{
sum[rt] = (r - l + 1) * val;
lazy[rt] = val;
return;
}
int mid = (l + r) >> 1;
PushDown(rt, mid - l + 1, r - mid);
if(L <= mid)
Update(L, R, val, lson);
if(mid < R)
Update(L, R, val, rson);
PushUp(rt);
return;
}
int Query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
return sum[rt];
int mid = (l + r) >> 1;
PushDown(rt, mid - l + 1, r - mid);
int ans = 0;
if(L <= mid)
ans += Query(L, R, lson);
if(mid < R)
ans += Query(L, R, rson);
return ans;
}
int main()
{
int n, q;
scanf("%d", &n);
Build(1, n, 1);
scanf("%d", &q);
while(q --)
{
int tp, l, r, val;
scanf("%d", &tp);
if(tp == 1)
{
scanf("%d %d %d", &l, &r, &val);
Update(l, r, val, 1, n, 1);
}
else
{
scanf("%d %d", &l, &r);
printf("%d\n", Query(l, r, 1, n, 1));
}
}
}
相關文章
- 芻議線段樹 2 (區間修改,區間查詢)
- HDU 1698 Just a Hook (線段樹區間更新)Hook
- POJ 3468 A Simple Problem with Integers (線段樹 區間更新)
- Codeforces 52C (線段樹區間更新)
- POJ 3468 【區間修改+區間查詢 樹狀陣列 | 線段樹 | 分塊】陣列
- POJ 3468-A Simple Problem with Integers(區間更新線段樹)
- 線段樹(3)——區間操作疊加
- 1082 線段樹練習 3 區間查詢與區間修改
- 線段樹維護區間等差數列
- HDU1698 Just a Hook【線段樹基礎:區間修改+區間查詢】Hook
- 線段樹模板
- POJ 2528 Mayor's posters (線段樹 區間更新+離散化)
- POJ 2528 Mayor's posters (線段樹區間更新 + 離散化)
- HDU 1754 I Hate It (線段樹 區間最值)
- POJ 3468 A Simple Problem with Integers(線段樹區間操作)
- Java 演算法-區間求和I(線段樹)Java演算法
- 區間k小值(可持久化線段樹)持久化
- Codeforces 272C Dima and Staircase (線段樹區間更新 或 線性掃)AI
- hdu 2665 可持久化線段樹求區間第K大值(函式式線段樹||主席樹)持久化函式
- POJ 3468 A Simple Problem with Integers (線段樹 區間共加)
- HDU1754 I Hate It 【線段樹基礎:點修改+區間查詢】
- 1080 線段樹練習 單點修改及區間查詢
- 區間演算法題用線段樹可以秒解?演算法
- 線段樹(1)建樹、單點修改、單點查詢、區間查詢和例題
- 線段樹模板總結
- 1081 線段樹練習 2 單點查詢及區間修改
- [18/03/24] 線段樹模板
- 【筆記/模板】線段樹(改)筆記
- 線~段~樹
- 線段樹
- POJ 2777-Count Color(線段樹-區間染色查詢)
- 【知識點】淺入線段樹與區間最值問題
- 一些線段樹典(求求了區域賽遇到線段樹不要被卡了)
- POJ 3264-Balanced Lineup詳解(線段樹區間求值)
- HDU1166 敵兵佈陣【線段樹基礎:點修改+區間查詢】
- 線段樹+差分——【模板】樹狀陣列2陣列
- 【Leetcode每日一題】327. 區間和的個數(線段樹/樹狀陣列)LeetCode每日一題陣列
- 線段樹 hate it