奇偶線段樹(區間更新)

2021-07-04 14:29:24 字數 1600 閱讀 4865

題意:給你乙個長度為n的陣列(下標從1開始)。進行如下操作。

(1)1 x y v :表示將下標=(x,x+2,x+4,x+6,.......並且<=y)的元素全部+v;

(2)2 x y :查詢[x,y]閉區間的元素和。

思路:構造2棵線段樹。

將區間[1,3,...,2k - 1]改為[1,2,...,k],用一棵線段樹統計這個區間內的和。

將區間[2,4,...,2k]改為[1,2,...,k],用一棵線段樹統計這個區間內的和。

剩下為普通的區間更新即可。

**:

#include #include #include #include #include #include using namespace std;

#define lson l, m, rt << 1

#define rson m + 1, r, rt << 1 | 1

#define ceil(x, y) (((x) + (y) - 1) / (y))

const int n = 1e5 + 10;

const int inf = 0x7f7f7f7f;

struct node ;

node node[3][n << 2];//0 偶線段樹 1 奇線段樹

long long a[n];

void pushup(int op, int rt)

void pushdown(int op, int rt, int len)

}void build(int op, int l, int r, int rt)

int m = (l + r) >> 1;

build(op, lson);

build(op, rson);

pushup(op, rt);

}void update(int op, int l, int r, long long c, int l, int r, int rt)

pushdown(op, rt, r - l + 1);

int m = (l + r) >> 1;

if (l <= m)

update(op, l, r, c, lson);

if (r > m)

update(op, l, r, c, rson);

pushup(op, rt);

}long long query(int op, int l, int r, int l, int r, int rt)

pushdown(op, rt, r - l + 1);

int m = (l + r) >> 1;

long long ql = 0, qr = 0;

if (l <= m)

ql = query(op, l, r, lson);

if (r > m)

qr = query(op, l, r, rson);

pushup(op, rt);

return ql + qr;

}int main()

for (int i_q = 1; i_q <= m; i_q++)

else

} }return 0;

}

線段樹區間更新

在此我們之前學習了線段樹的單點更新 點我 但是現在我們遇到乙個這樣的問題 給出乙個n個元素的陣列a1,a2,an。我們總共進行m次操作。每次操作為下列兩種操作其中一種 1 add l,r,v 將a l a l 1 a r 的值全部增加v。2 query l,r 計算子串行a l a l 1 a r ...

線段樹(區間更新求和)

poj 3468 include using namespace std define max 100100 struct node 求區間長度 int get dis node tree max 3 long long d max 建樹 long long build int left,int r...

線段樹之區間更新

為什麼這樣?答案是顯然的。線段樹的查詢和單點更新的時間複雜度是o logn 的,如果我每次都只是更新乙個節點,再去詢問,那麼複雜度是o nlogn 這個複雜度是可以接受的,但是如果每次操作我都是更新乙個區間,還是用單點更新去做,那麼複雜度是o n 2logn 這個複雜度是很大的,一般來說,在acm競...