Title Link:http://ccnu.acmclub.com/index.php?app=problem_title&id=613&problem_id=23875
Test instructions: give you an array of length n (subscript starting from 1). Do the following.
(1) 1 x y V: means subscript = (x,x+2,x+4,x+6, ...). And the elements of <=y) are all +v;
(2) 2 x y: The Elements of the [x, y] closed interval are queried.
idea: Construct 2 tree segments. Change the interval [1,3,...,2k-1] to [1,2,...,k] and use a segment tree to count the and within the interval. Change the interval [2,4,...,2k] to [1,2,...,k] and use a segment tree to count the and within the interval. The rest is the normal interval update.
Code:
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include < Algorithm> #include <string>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 {Long Long Sum;lo ng long add;}; Node node[3][n << 2];//0 even segment tree 1 odd segment tree long long a[n];void pushup (int op, int rt) {node[op][rt].sum = Node[op][rt <& Lt 1].sum + node[op][rt << 1 | 1].sum;} void pushdown (int op, int rt, int len) {int lenl = (len-(Len >> 1)), int lenr = (len >> 1); if (node[op][rt].a DD) {node[op][rt << 1].sum + = 1LL * LENL * node[op][rt].add;node[op][rt << 1 | 1].sum + 1LL * lenr * Node[op] [Rt].add;node[op][rt << 1].add + node[op][rt].add;node[op][rt << 1 | 1].add + = NODE[OP][RT].ADD;NODE[OP][RT ].add = 0;}} void Build (int op, int l, int r, int rt) {Node[op][rt].add = 0;if (L = = r) {if (OP)Node[op][rt].sum = a[2 * l-1];elsenode[op][rt].sum = a[2 * L];return;} int m = (L + R) >> 1;build (OP, Lson); Build (OP, Rson);p ushup (OP, RT);} void Update (int op, int l, int r, long long c, int l, int R, int rt) {if (L <= l && R <= R) {node[op][rt].su M + = 1LL * (r-l + 1) * c;node[op][rt].add + = C;return;} 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);p ushup (OP, RT);} Long Long query (int op, int l, int r, int l, int r, int rt) {if (L <= l && R <= R) {return node[op][rt].sum; }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);p ushup (OP, RT); return QL + qr;} int main () {int t_case;scanf ("%d", &t_case), for (int i_case = 1; i_case <= t_case; i_case++) {int n, m;int no, ne;b Ool flag = false;scanf ("%d%d", &n, &m); for (int i = 1; I <= n; i++) scanf ("%lld", &a[i]); no = Ceil (n, 2), NE = n-no;build (1, 1, no, 1), if (NE) {//Whether it is necessary to build even segment tree build (0, 1, NE, 1); flag = true;} for (int i_q = 1; i_q <= m; i_q++) {int op, L, r;scanf ("%d%d%d", &op, &l, &r); if (op = = 1) {Long Long V;sca NF ("%lld", &v), if ((L + R) & 1) r--;if (L & 1) Update (1, Ceil (L, 2), Ceil (R, 2), V, 1, no, 1); else update (0, CEI L (L, 2), Ceil (R, 2), V, 1, NE, 1);} else {int Ol = Ceil ((L & 1? L:l + 1), 2), int Or = Ceil ((R & 1? R:r-1), 2); int El = Ceil ((L & 1? l + 1 : l), 2); int Er = Ceil (R & 1? R-1: R), 2); long long Qo = 0, QE = 0;if (Ol <= Or)//interval Legal QO = query (1, Ol, Or, 1 , no, 1); if (flag && el <= Er) QE = query (0, El, er, 1, NE, 1);p rintf ("%lld\n", Qo + QE);}} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Odd-even segment tree (interval update)