• 树状数组 && 线段树


    树状数组

    支持单点修改

    #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]维护序列的题解

  • 相关阅读:
    Unity3D ShaderLab 立方体图的反射遮罩
    Unity3D ShaderLab 简单的立方体图反射
    Unity3D ShaderLab 各向异性高光
    Unity3D ShaderLab 使用贴图对模型的高光进行遮罩
    Unity3D ShaderLab 使用BlinnPhong高光类型
    Unity3D ShaderLab 创建自定义高光类型
    Unity3D ShaderLab 基础的高光实现
    Unity3D ShaderLab法线贴图
    Unity3D ShaderLab压缩混合纹理贴图
    Java几种建立实例的方法
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6641336.html
Copyright © 2020-2023  润新知