zoukankan      html  css  js  c++  java
  • 树状数组 && 线段树

    树状数组

    支持单点修改

    #include <cstdio>
    
    using namespace std;
    
    int n, m;
    int a[500001], c[500001];
    
    int lowbit(int x)
    {
        return x & -x;
    }
    
    int sum(int x)
    {
        int ans = 0;
        while(x)
        {
            ans += c[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    void add(int x, int d)
    {
        while(x <= n)
        {
            c[x] += d;
            x += lowbit(x);
        }
    }
    
    int main()
    {
        int i, j, x, y, z;
        scanf("%d %d", &n, &m);
        for(i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            add(i, a[i]);
        }
        for(i = 1; i <= m; i++)
        {
            scanf("%d %d %d", &z, &x, &y);
            if(z == 1) add(x, y);
            else printf("%d
    ", sum(y) - sum(x - 1));
        }
        return 0;
    }
    View Code

    支持区间修改

    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    int n, m;
    long long c0[100001], c1[100001], a[100001];
    
    long long lowbit(int x) {return x & -x;}
    
    long long sum(long long *c, int x)
    {
        long long ans = 0;
        while(x)
        {
            ans += c[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    void add(long long *c, int x, int d)
    {
        while(x <= n)
        {
            c[x] += d;
            x += lowbit(x);
        }
    }
    
    int main()
    {
        int i, j, x, y, z, k;
        long long ans;
        scanf("%d%d", &n, &m);
        for(i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            add(c0, i, a[i]);
        }
        for(i = 1; i <= m; i++)
        {
            scanf("%d%d%d", &z, &x, &y);
            if(z == 1)
            {
                scanf("%d", &k);
                add(c0, x, -k * (x - 1));
                add(c1, x, k);
                add(c0, y + 1, k * y);
                add(c1, y + 1, -k);
            }
            else
            {
                ans = 0;
                ans += sum(c0, y) + sum(c1, y) * y;
                ans -= sum(c0, x - 1) + sum(c1, x - 1) * (x - 1);
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
    View Code

    线段树

    支持区间修改

    add[o]表示节点o的lazy标记,且节点o已经修改完

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    
    using namespace std;
    
    #define root 1, 1, N
    #define ls o << 1, l, m
    #define rs o << 1 | 1, m + 1, r
    
    int L, R;
    long long add[1500005], mul[1500005], c[1500005], P;
    
    inline int read()
    {
        int x = 0, f = 1;
        char ch = getchar();
        while(!isdigit(ch))
        {
            if(ch == '-') f = -1;
            ch = getchar();
        }
        while(isdigit(ch))
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    
    inline void pushup(int o)
    {
        c[o] = (c[o << 1] + c[o << 1 | 1]) % P;
    }
    
    inline void build(int o, int l, int r)
    {
        add[o] = 0;
        mul[o] = 1;
        if(l == r)
        {
            scanf("%lld", &c[o]);
            return;
        }
        int m = (l + r) >> 1;
        build(ls);
        build(rs);
        pushup(o);
    }
    
    inline void pushdown(int o, int m)
    {
        if(add[o] == 0 && mul[o] == 1) return;
        c[o << 1] = (c[o << 1] * mul[o] + add[o] * (m - (m >> 1))) % P;
        c[o << 1 | 1] = (c[o << 1 | 1] * mul[o] + add[o] * (m >> 1)) % P;
        add[o << 1] = (add[o << 1] * mul[o] + add[o]) % P;
        add[o << 1 | 1] = (add[o << 1 | 1] * mul[o] + add[o]) % P;
        mul[o << 1] = (mul[o << 1] * mul[o]) % P;
        mul[o << 1 | 1] = (mul[o << 1 | 1] * mul[o]) % P;
        add[o] = 0;
        mul[o] = 1;
    }
    
    inline void update(int f, int d, int o, int l, int r)
    {
        if(L <= l && r <= R)
        {
            if(f == 2)
            {
                add[o] = (add[o] + d) % P;
                c[o] = (c[o] + d * (r - l + 1)) % P;
            }
            else
            {
                mul[o] = (mul[o] * d) % P;
                add[o] = (add[o] * d) % P;
                c[o] = (c[o] * d) % P;
            }
            return;
        }
        pushdown(o, r - l + 1);
        int m = (l + r) >> 1;
        if(L <= m) update(f, d, ls);
        if(m < R) update(f, d, rs);
        pushup(o);
    }
    
    inline long long query(int o, int l, int r)
    {
        if(L <= l && r <= R) return c[o];
        pushdown(o, r - l + 1);
        int m = (l + r) >> 1;
        long long ret = 0;
        if(L <= m) ret += query(ls);
        if(m < R) ret += query(rs);
        return ret;
    }
    
    int main()
    {
        int N, Q;
        N = read();
        P = read();
        build(root);
        Q = read();
        while(Q--)
        {
            int a, x, y, k;
            a = read();
            if(a == 1 || a == 2)
            {
                x = read();
                y = read();
                k = read();
                L = x;
                R = y;
                update(a, k, root);
            }
            else
            {
                x = read();
                y = read();
                L = x;
                R = y;
                printf("%lld
    ", query(root) % P);
            }
        }
        return 0;
    }
    View Code

     ps:有意思的是这个代码还是[AHOI2009]维护序列的题解

  • 相关阅读:
    我是服务的执政官-服务发现和注册工具consul简介
    跳闸了啊! 服务容灾:熔断器简介
    论获取缓存值的正确姿势
    容器化redis高可用方案
    ASP.NET SessionState 解惑
    Thymeleaf 模板的使用
    记录js的一个图片预览功能代码
    记录一个简单的可以拖动的弹出层
    oracle安装报错[INS-30131]执行安装程序验证所需的初始设置失败(无法访问临时位置)解决方法!
    nginx学习笔记2
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6641336.html
Copyright © 2011-2022 走看看