zoukankan      html  css  js  c++  java
  • 【算法

    单点修改

    struct SegmentTree {
    
    #define ls (u << 1)
    #define rs (u << 1 | 1)
    #define mid ((l + r) >> 1)
    
        static const int MAXN = 5e5 + 10;
        static const ll LINF = 1e18 + 10;
    
        int n;
        ll sum[MAXN << 2];
    
        void iBuild(int u, int l, int r) {
            if (l > r) { return; }
            if (l == r) { sum[u] = a[l];}
            else {
                iBuild(ls, l, mid);
                iBuild(rs, mid + 1, r);
                sum[u] = sum[ls] + sum[rs];
            }
        }
    
        void iAdd(int u, int l, int r, int pos, ll val) {
            if (l > r || pos < l || pos > r) { return; }
            if (l == r) { sum[u] += val; }
            else {
                iAdd(ls, l, mid, pos, val);
                iAdd(rs, mid + 1, r, pos, val);
                sum[u] = sum[ls] + sum[rs];
            }
        }
    
        ll iSum(int u, int l, int r, int L, int R) {
            ll res = 0;
            if (l > r || L > R || L > r || R < l) { return res; }
            if (L <= l && r <= R) { res = sum[u]; }
            else {
                res += iSum(ls, l, mid, L, R);
                res += iSum(rs, mid + 1, r, L, R);
            }
            return res;
        }
    
    #undef ls
    #undef rs
    #undef mid
    
    } tree;
    
    完整功能模板代码
    struct SegmentTree {
    
    private:
    
    #define ls (u << 1)
    #define rs (u << 1 | 1)
    #define mid ((l + r) >> 1)
    
        static const int MAXN = 5e5 + 10;
        static const ll LINF = 1e18 + 10;
    
        int n;
        int *a1;
        ll *a2;
    
        struct Node {
            int l, r;
            ll sum;
            ll mi;
            ll ma;
            Node() {
                l = -1, r = -1,
                sum = 0;
                mi = LINF;
                ma = -LINF;
            }
            Node &operator=(ll val) {
                sum = val;
                mi = val;
                ma = val;
                return *this;
            }
            Node &operator+=(ll val) {
                sum += val;
                mi += val;
                ma += val;
                return *this;
            }
            void show() {
                printf("  [%d, %d] sum=%lld mi=%lld ma=%lld
    ", l, r, sum, mi, ma);
            }
        } node[MAXN << 2];
    
        Node mergeFrom(const Node &x, const Node &y) {
            if (x.l == -1 && x.r == -1)
                return y;
            if (y.l == -1 && y.r == -1)
                return x;
            Node res;
            res.l = x.l, res.r = y.r;
            res.sum = x.sum + y.sum;
            res.mi = min(x.mi, y.mi);
            res.ma = min(x.ma, y.ma);
            return move(res);
        }
    
        void iBuild(int u, int l, int r) {
            if (l > r) { return; }
            if (l == r) {
                node[u] = Node();
                node[u].l = l;
                node[u].r = l;
                if (a1 != nullptr)
                    node[u] = a1[l];
                if (a2 != nullptr)
                    node[u] = a2[l];
            } else {
                iBuild(ls, l, mid);
                iBuild(rs, mid + 1, r);
                node[u] = mergeFrom(node[ls], node[rs]);
            }
        }
    
        void iSet(int u, int l, int r, int pos, ll val) {
            if (l > r || pos < l || pos > r) { return; }
            if (l == r) { node[u] = val; }
            else {
                if (pos <= mid) { iSet(ls, l, mid, pos, val); }
                if (pos >= mid + 1) { iSet(rs, mid + 1, r, pos, val); }
                node[u] = mergeFrom(node[ls], node[rs]);
            }
        }
    
        void iAdd(int u, int l, int r, int pos, ll val) {
            if (l > r || pos < l || pos > r) { return; }
            if (l == r) { node[u] += val; }
            else {
                if (pos <= mid) { iAdd(ls, l, mid, pos, val); }
                if (pos >= mid + 1) { iAdd(rs, mid + 1, r, pos, val); }
                node[u] = mergeFrom(node[ls], node[rs]);
            }
        }
    
        Node iQuery(int u, int l, int r, int L, int R) {
            Node res;
            if (l > r || L > R || L > r || R < l) { return res; }
            if (L <= l && r <= R) { res = node[u]; }
            else {
                if (L <= mid) { res = mergeFrom(iQuery(ls, l, mid, L, R), res); }
                if (R >= mid + 1) { res = mergeFrom(res, iQuery(rs, mid + 1, r, L, R)); }
            }
            return res;
        }
    
    #undef ls
    #undef rs
    #undef mid
    
    public:
    
        void Build(int n) {
            this->n = n, this->a1 = nullptr, this->a2 = nullptr;
            iBuild(1, 1, n);
        }
    
        void Build(int n, int *a) {
            this->n = n, this->a1 = a, this->a2 = nullptr;
            iBuild(1, 1, n);
        }
    
        void Build(int n, ll *a) {
            this->n = n, this->a1 = nullptr, this->a2 = a;
            iBuild(1, 1, n);
        }
    
        void Set(int pos, ll val) {
    //        printf("Set %d, %lld
    ", pos, val);
            iSet(1, 1, n, pos, val);
        }
    
        void Add(int pos, ll val) {
    //        printf("Add %d, %lld
    ", pos, val);
            iAdd(1, 1, n, pos, val);
        }
    
        Node Query(int L, int R) {
    //        printf("Query [%d, %d]
    ", L, R);
            return iQuery(1, 1, n, L, R);
        }
    
        ll Sum(int L, int R) { return Query(L, R).sum; }
        ll Min(int L, int R) { return Query(L, R).mi; }
        ll Max(int L, int R) { return Query(L, R).ma; }
    
    } tree;
    

    验证链接:https://www.luogu.com.cn/problem/P3374

    区间修改

    struct SegmentTree {
    
    #define ls (u << 1)
    #define rs (u << 1 | 1)
    #define mid ((l + r) >> 1)
    
        static const int MAXN = 1e5 + 10;
        static const ll LINF = 1e18 + 10;
    
        int n;
        ll tag[MAXN << 2];
        ll sum[MAXN << 2];
    
        void pushUp(int u) {
            sum[u] = sum[ls] + sum[rs];
        }
    
        void pushDown(int u, int l, int r) {
            ll t = tag[u];
            if (t != 0) {
                tag[ls] += t;
                sum[ls] += 1LL * (mid - l + 1) * t;
                tag[rs] += t;
                sum[rs] += 1LL * (r - mid) * t;
                tag[u] = 0;
            }
        }
    
        void iBuild(int u, int l, int r) {
            if (l > r) { return; }
            tag[u] = 0;
            if (l == r) { sum[u] = a[l];}
            else {
                iBuild(ls, l, mid);
                iBuild(rs, mid + 1, r);
                pushUp(u);
            }
        }
    
        void iAdd(int u, int l, int r, int L, int R, ll val) {
            if (l > r || L > R || L > r || R < l) { return; }
            if (L <= l && r <= R) {
                tag[u] += val;
                sum[u] += 1LL * (r - l + 1) * val;
            } else {
                pushDown(u, l, r);
                iAdd(ls, l, mid, L, R, val);
                iAdd(rs, mid + 1, r, L, R, val);
                pushUp(u);
            }
        }
    
        ll iSum(int u, int l, int r, int L, int R) {
            ll res = 0;
            if (l > r || L > R || L > r || R < l) { return res; }
            if (L <= l && r <= R) { res = sum[u]; }
            else {
                pushDown(u, l, r);
                res += iSum(ls, l, mid, L, R);
                res += iSum(rs, mid + 1, r, L, R);
            }
            return res;
        }
    
    #undef ls
    #undef rs
    #undef mid
    
    } tree;
    

    单点修改 字符串哈希

    用来维护字符串哈希时,需要注意的是额外维护真实的左区间的长度。

  • 相关阅读:
    sql 数据库还原脚本 (kill链接+独占
    最长回文字符串
    UVa 455 Periodic Strings
    UVa 1225 Digit Counting
    UVa 340 Master-Mind Hints
    UVa 10976
    UVa 725
    UVa 11059
    POJ1887 最长下降子序列
    最大连续子序列算法(数组的连续子数组最大和(首尾不相连))
  • 原文地址:https://www.cnblogs.com/purinliang/p/13665942.html
Copyright © 2011-2022 走看看