zoukankan      html  css  js  c++  java
  • 【模板】线段树

    计蒜客:

    注:计蒜客相关解释十分清晰,不清楚的代码可直接看分析

    基础:

    对线段树区间的理解+对结点个数的理解

    O(n)地递归建立线段树 (代码实现)

    O(logn)单点修改 (代码实现) O(logn)单点查询

    O(logn)区间查询  (代码实现)

     进阶:(lazy标记)

    O(logn)区间修改    (代码实现)

    O(logn)区间查询(不同于上面的区间查询哦) (代码实现)

     有lazy的地方保证权值正确,它的下一个地方权值才是不正确的

    部分基础代码

    #include <iostream>
    using namespace std;
    const int inf_ = 0x3f3f3f3f;
    const int maxN_ = 110;
    int a[maxN_];
    class BinaryIndexedTree_ {
    public:
      #define lId id << 1
      #define rId id << 1 | 1
      #define mid_ int mid = (l + r) >> 1
      int minv[4 * maxN_];
      void PushUp(int id) { minv[id] = min(minv[lId], minv[rId]); }
      void Build(int id, int l, int r) {
        if (l == r) {
          minv[id] = a[l];
          return;
        }
        mid_;
        Build(lId, l, mid);
        Build(rId, mid + 1, r);
        PushUp(id);
      }
      void UpDate(int id, int l, int r, int x, int v) {
        if (l == r) {
          minv[id] = v;
          return;
        }
        mid_;
        if (x <= mid) {
          UpDate(lId, l, mid, x, v);
        } else {
          UpDate(rId, mid + 1, r, x, v);
        }
        PushUp(id);
      }
      int Query(int id, int l, int r, int x, int y) {
        if (x <= l && r <= y) {
          return minv[id];
        }
        mid_;
        int ans = inf_;
        if (x <= mid) {
          ans = min(ans, Query(lId, l, mid, x, y));
        }
        if (y > mid) {
          ans = min(ans, Query(rId, mid + 1, r, x, y));
        }
        return ans;
      }
    } bit;
    int main() {
      int n;
      for (int i = 1; i <= n; ++i) {
        cin >> a[i];
      }
      bit.Build(1, 1, n);
      int q;
      cin >> q;
      for (int i = 0; i < q; ++i) {
        int x, v;
        cin >> x >> v;
        bit.UpDate(1, 1, n, x, v);
      }
      int p;
      cin >> p;
      for (int i = 0; i < p; ++i) {
        int l, r;
        cin >> l >> r;
        cout << bit.Query(1, 1, n, l, r) << endl;
      }
      return 0;
    }
    View Code

    基础部分代码

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <queue>
    #include <iomanip>
    #include <iostream>
    #include <stack>
    using namespace std;
    
    ///-------------------------------------------------------常用规定部分
    //----------------------便于更改
    // nodeType(1~1e7) 都是int就不必麻烦了
    #define valueType_ int // valueType(1~1e19)
    //----------------------通用
    #define inf_ 0x3f3f3f3f //这是给int的inf,值为1061109567,2^31-1为2147483647
    #define reg_ register int
    #define for_(i, n) for (int i = 1; i <= n; i++)
    #define forReg_(i, n) for (reg_ i = 1; i <= n; i++)
    #define ll_ long long
    #define ull_ unsigned long long
    //----------------------其它
    const int maxN_ = 1e2 + 10;
    const int maxM_ = 1e4 + 10;
    ///-------------------------------------------------------变量声明部分
    //--------------------------------------其它
    int a[maxN_];
    class SEGMENT_TREE {
    public:
      //宏定义
    #define mid_ int mid = (l + r) >> 1 // mid的定义
    #define len_ (r - l + 1)
    #define lId_ id << 1
    #define rId_ id << 1 | 1
    #define lSon_ id << 1, l, mid
    #define rSon_ id << 1 | 1, mid + 1, r
    #define include_(x, y, l, r) x <= l &&r <= y
      // data
      int minv[4 * maxN_], lazy[4 * maxN_];
      // function
      void PushUp(int id) { minv[id] = min(minv[lId_], minv[rId_]); }
      void PushDown(int id) {
        if (lazy[id]) {
          lazy[lId_] += lazy[id];
          lazy[rId_] += lazy[id];
          minv[lId_] += lazy[id];
          minv[rId_] += lazy[id];
          lazy[id] = 0;
        }
      }
      void Build(int id, int l, int r) {
        if (l == r) {
          minv[id] = a[l];
          return;
        }
        mid_;
        Build(lSon_);
        Build(rSon_);
        PushUp(id);
      }
      void UpDate(int id, int l, int r, int x, int y, int v) {
        if (x <= l && r <= y) {
          lazy[id] += v;
          minv[id] += v;
          return;
        }
        PushDown(id);
        mid_;
        if (x <= mid) {
          UpDate(lSon_, x, y, v);
        }
        if (y > mid) {
          UpDate(rSon_, x, y, v);
        }
        PushUp(id);
      }
      int Query(int id, int l, int r, int x, int y) {
        if (x <= l && r <= y) {
          return minv[id];
        }
        PushDown(id);
        mid_;
        int ans = inf_;
        if (x <= mid) {
          ans = min(ans, Query(lSon_, x, y));
        }
        if (y > mid) {
          ans = min(ans, Query(rSon_, x, y));
        }
        return ans;
      }
    } tree;
    ///--------------------------------------------------------函数声明部分
    //--------------------------------------其它
    
    ///--------------------------------------------------------main函数部分
    int main() {
      // freopen("in.txt","r", stdin);
      // freopen("out.txt","w", stdout);
      ios::sync_with_stdio(false);
      // InitEdge();
      int n;
      cin >> n;
      for (int i = 1; i <= n; ++i) {
        cin >> a[i];
      }
      tree.Build(1, 1, n);
      int q;
      cin >> q;
      while (q--) {
        int x, y, v;
        cin >> x >> y >> v;
        tree.UpDate(1, 1, n, x, y, v);
      }
      cin >> q;
      while (q--) {
        int x, y;
        cin >> x >> y;
        cout << tree.Query(1, 1, n, x, y) << endl;
      }
      return 0;
    }
    ///--------------------------------------------------------函数定义部分
    //----------------------------------其它
    /*
    data:
    5
    1 2 3 4 5
    2
    1 5 1
    2 4 -4
    2
    1 5
    5 5
    ans:
    -1
    5
    */
    View Code
  • 相关阅读:
    C#反射
    做下一周计划
    OFFSET 函数
    微信跳一跳学习笔记
    跳一跳脚本代码搬运
    预测羽毛球赛成绩学习笔记
    将Python123中作业成绩绘制成雷达图
    Matplotlib库
    Numpy库
    第四周作业
  • 原文地址:https://www.cnblogs.com/bear-xin/p/14688573.html
Copyright © 2011-2022 走看看