切完了我的第一颗线段树
作者:互联网
题目是洛谷的P3372,可以去看一下,传送门
算是常规模板了,先声明一下,我是数组爱好者,不喜欢用struct。代码在下面。
#include <bits/stdc++.h> using namespace std; #define MAXN 1000005 typedef long long ll; ll n, m, a[MAXN], ans[MAXN << 2], tag[MAXN << 2], x, y, k, oper; inline ll ls(ll p) { return p << 1; } inline ll rs(ll p) { return p << 1 | 1; } inline void push_up(ll p) { //do add ans[p] = ans[ls(p)] + ans[rs(p)]; } void build(ll p, ll l, ll r) { tag[p] = 0; if (l == r) { ans[p] = a[l]; return; } ll mid = l + r >> 1; build(ls(p), l, mid); build(rs(p), mid + 1, r); push_up(p); } inline void f(ll p, ll l, ll r, ll k) { //only modify ancestor tag[p] += k; ans[p] += k * (r - l + 1); } inline void push_down(ll p, ll l, ll r) { ll mid = (l + r) >> 1; f(ls(p), l, mid, tag[p]); f(rs(p), mid + 1, r, tag[p]); tag[p] = 0; } inline void update(ll dl, ll dr, ll l, ll r, ll p, ll k) { if (dl <= l && r <= dr) { ans[p] += k * (r - l + 1); tag[p] += k; return; } push_down(p, l, r); ll mid = l + r >> 1; if (dl <= mid)update(dl, dr, l, mid, ls(p), k); if (mid < dr)update(dl, dr, mid + 1, r, rs(p), k); push_up(p); } ll query(ll qx, ll qy, ll l, ll r, ll p) { ll res = 0; if (qx <= l && r <= qy)return ans[p]; ll mid = l + r >> 1; push_down(p, l, r); if (qx <= mid)res += query(qx, qy, l, mid, ls(p)); if (qy > mid)res += query(qx, qy, mid + 1, r, rs(p)); return res; } int main() { scanf("%lld%lld", &n, &m); for (int i = 1; i <= n; i++)scanf("%lld", &a[i]); build(1, 1, n); while (m--) { scanf("%lld", &oper); if (oper == 1) { scanf("%lld%lld%lld", &x, &y, &k); update(x, y, 1, n, 1, k); } else { scanf("%lld%lld", &x, &y); printf("%lld\n", query(x, y, 1, n, 1)); } } return 0; }
标签:dl,线段,mid,tag,MAXN,void,第一颗,切完,ll 来源: https://www.cnblogs.com/creation-hy/p/my_first_segment_tree.html