C++实现线段树(lazy-tag方法)-区间修改,区间查询
生活随笔
收集整理的這篇文章主要介紹了
C++实现线段树(lazy-tag方法)-区间修改,区间查询
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
代碼如下:
#include <iostream> using namespace std; const int N = 10010; typedef long long LL; LL input[N];struct node {int l, r;LL sum;LL add; } tree[4 * N];void build(int l, int r, int u) {tree[u].l = l;tree[u].r = r;if (l == r) {tree[u].sum = input[l];return ;}int mid = (l + r) >> 1;build(l, mid, 2 * u);build(mid + 1, r, 2 * u + 1);tree[u].sum = tree[2 * u].sum + tree[2 * u + 1].sum; }void spread(int u) {if (tree[u].add) //當lazy tag不為0時,說明當前區間已經被這個影響所作用,//這個區間的所有子區間全都攢著工作沒有修改{tree[2 * u].add += tree[u].add;tree[2 * u + 1].add += tree[u].add;tree[2 * u].sum += tree[u].add * (tree[2 * u].r - tree[2 * u].l + 1);tree[2 * u + 1].sum += tree[u].add * (tree[2 * u + 1].r - tree[2 * u + 1].l + 1);tree[u].add = 0;} }void update(int cl, int cr, int w, int u) {if (tree[u].l >= cl && tree[u].r <= cr) {tree[u].sum += (LL)w * (tree[u].r - tree[u].l + 1);tree[u].add += (LL)w;return ;}spread(u);int mid = (tree[u].l + tree[u].r) >> 1;if (cl <= mid)update(cl, cr, w, 2 * u);if (cr > mid)//不能寫成(cr >= mid),不然可能會死循環update(cl, cr, w, 2 * u + 1);tree[u].sum = tree[2 * u].sum + tree[2 * u + 1].sum; }LL query(int cl, int cr, int u) {if (tree[u].l >= cl && tree[u].r <= cr)return tree[u].sum;spread(u);int mid = (tree[u].l + tree[u].r) >> 1;LL ans = 0;if (cl <= mid)ans += query(cl, cr, 2 * u);if (cr > mid)ans += query(cl, cr, 2 * u + 1); // cout << ans << endl;return ans; }int main() {int n;cin >> n;for (int i = 1; i <= n; i++)cin >> input[i];build(1, n, 1);cout << query(3, 6, 1) << endl;//查詢區間[3,6]所有元素之和update(3, 6, 3, 1);//給區間[3,6]所有元素加上3cout << query(3, 6, 1) << endl;//再次查詢區間[3,6]所有元素之和return 0; }測試結果:
總結
以上是生活随笔為你收集整理的C++实现线段树(lazy-tag方法)-区间修改,区间查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何成为番茄小说的一名作者怎么在番茄小说
- 下一篇: C++未定义行为-数组越界