网址如下:
P3372 【模板】线段树 1 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题如其名
昨天做了一道开关(也是线段树的)
想着今天复习一下
代码如下:
#include<iostream>
using namespace std;
typedef long long ll;
ll query(int l, int r, int p, int cl, int cr);
void update(int l, int r, ll d, int p, int cl, int cr);
void build(int l, int r, int p);
ll tree[100000000], mark[100000000], element[100001], k;
int n, m, x, y;int main(void)
{//输入cin >> n >> m;for(int i = 1; i <= n; i++)cin >> element[i];//处理build(1, n, 1);for(int i = 0; i < m; i++){int n_switch;cin >> n_switch;if(n_switch == 1){cin >> x >> y >> k;update(x, y, k, 1, 1, n);}else{cin >> x >> y;cout << query(x, y, 1, 1, n) << endl;}}return 0;
}
ll query(int l, int r, int p, int cl, int cr)
{if(cl > r || cr < l)return 0;if(cl >= l && cr <= r)return tree[p];else{int mid = (cl + cr) / 2;tree[2 * p] += mark[p] * (ll)(mid - cl + 1), tree[2 * p + 1] += mark[p] * (ll)(cr - mid);mark[2 * p] += mark[p], mark[2 * p + 1] += mark[p];mark[p] = 0;return query(l, r, 2 * p, cl, mid) + query(l, r, 2 * p + 1, mid + 1, cr);}
}
void update(int l, int r, ll d, int p, int cl, int cr)
{if(cl > r || cr < l)return;if(cl >= l && cr <= r){mark[p] += d;tree[p] += d * (ll)(cr - cl + 1);}else{int mid = (cl + cr) / 2;tree[2 * p] += mark[p] * (ll)(mid - cl + 1), tree[2 * p + 1] += mark[p] * (ll)(cr - mid);mark[2 * p] += mark[p], mark[2 * p + 1] += mark[p];mark[p] = 0;update(l, r, d, 2 * p, cl, mid), update(l, r, d, 2 * p + 1, mid + 1, cr);tree[p] = tree[2 * p] + tree[2 * p + 1];}
}
void build(int l, int r, int p)
{if(l < r){int mid = (l + r) / 2;build(l, mid, 2 * p), build(mid + 1, r, 2 * p + 1);tree[p] = tree[2 * p] + tree[2 * p + 1];}elsetree[p] = element[l];
}