线段树(区间求和+区间更新)(模板)

    科技2022-08-19  117

    题目: 传送门 改进: 相较于单点更新,引入lazy数组,lazy[node] = val表示当前节点(node)维护的子区间全部都要加上val(可正可负)。lazy标记在区间更新和区间查询时下传(push_down) Code:

    #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <vector> #include <map> #include <queue> #include <algorithm> using namespace std; typedef long long ll; typedef pair<int, int> P; const int inf = 0x3f3f3f3f; const int maxn = 1000007; int arr[maxn]; ll tree[4*maxn]; ll lazy[4*maxn]; int n, q; void push_down(int node, int m) { if (lazy[node]) { lazy[2*node] += lazy[node]; lazy[2*node+1] += lazy[node]; tree[2*node] += lazy[node] * (m - m/2); tree[2*node+1] += lazy[node] * (m/2); lazy[node] = 0; } } void push_up(int node) { tree[node] = tree[2*node] + tree[2*node+1]; } void build_tree(int node, int l, int r) { if (l == r) { tree[node] = arr[l]; return; } lazy[node] = 0; int mid = (l + r) / 2; build_tree(2*node, l, mid); build_tree(2*node+1, mid+1, r); push_up(node); } ll query_tree(int node, int l, int r, int fl, int fr) { if (l == fl && r == fr) { return tree[node]; } push_down(node, r - l + 1); int mid = (l + r) / 2; if (fr <= mid) { return query_tree(2*node, l, mid, fl, fr); } else if (mid < fl) { return query_tree(2*node+1, mid+1, r, fl, fr); } else { return query_tree(2*node, l, mid, fl, mid) + query_tree(2*node+1, mid+1, r, mid+1, fr); } } void add_tree(int node, int l, int r, int tl, int tr, int val) { if (l == tl && r == tr) { lazy[node] += val; tree[node] += (r - l + 1) * val; return; } push_down(node, r - l + 1); int mid = (l + r) / 2; if (tr <= mid) { add_tree(2*node, l, mid, tl, tr, val); } else if (tl > mid) { add_tree(2*node+1, mid+1, r, tl, tr, val); } else { add_tree(2*node, l, mid, tl, mid, val); add_tree(2*node+1, mid+1, r, mid+1, tr, val); } push_up(node); } int main() { scanf("%d %d", &n, &q); for (int i=1;i<=n;i++) { scanf("%d", &arr[i]); } build_tree(1, 1, n); char op; int a, b, c; while (q--) { scanf(" %c", &op); if (op == 'Q') { scanf("%d %d", &a, &b); printf("%lld\n", query_tree(1, 1, n, a, b)); } else if (op == 'C') { scanf("%d %d %d", &a, &b, &c); add_tree(1, 1, n, a, b, c); } } return 0; }
    Processed: 0.049, SQL: 9