• 洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)


    洛谷P2023 [AHOI2009]维护序列

    区间修改

    当我们要修改一个区间时,要保证 (ax+b) 的形式,即先乘后加的形式。当将区间乘以一个数 (k) 时,原来的区间和为 (ax+b) ,乘以 (k)(k(ax+b)=kax+kb)

    区间加一个数更加简单,原来的区间和为 (ax+b) ,加上一个 (k)(ax+b+k) ,合并 (b)(k)(ax+(b+k))

    标记下传

    [a(a'x+b')+b = (aa')cdot x + (ab'+b) ]

    #include<bits/stdc++.h>
    
    using namespace std;
    #define lson l, mid, root << 1
    #define rson mid + 1, r, root << 1 | 1
    
    const int maxn = 100005;
    long long tree[maxn << 2];
    int n, p, q;
    struct L{
        long long mul, add;
    }label[maxn << 2];
    
    inline void pushUp(int root)
    {
        tree[root] = (tree[root << 1] + tree[root << 1 | 1]) % p;
    }
    inline void pushDown(int root, int len)
    {
        if(label[root].add == 0 && label[root].mul == 1) return;
        else{
            tree[root << 1] = (label[root].mul * tree[root << 1] + label[root].add * (len - (len >> 1))) % p;/***长度划分***/
            tree[root << 1 | 1] = (label[root].mul * tree[root << 1 | 1] + label[root].add * (len >> 1)) % p;
            label[root << 1].add = (label[root].mul * label[root << 1].add + label[root].add) % p;
            label[root << 1 | 1].add = (label[root].mul * label[root << 1 | 1].add + label[root].add) % p;
            label[root << 1].mul = (label[root << 1].mul * label[root].mul) % p;
            label[root << 1 | 1].mul = (label[root << 1 | 1].mul * label[root].mul) % p;
            label[root].add = 0; label[root].mul = 1;
        }
    }
    void build(int l, int r, int root)
    {
        label[root].add = 0; label[root].mul = 1;
        if(l == r){
            scanf("%lld", &tree[root]); return;
        }
        int mid = (l + r) >> 1;
        build(lson); build(rson);
        pushUp(root);
    }
    void update(int l, int r, int root, int L, int R, int tag, int c)
    {
        if(L == l && R == r){
            if(tag == 1){
                tree[root] = tree[root] * c % p;
                label[root].add = label[root].add * c % p;
                label[root].mul = label[root].mul * c % p;
            }else{
                tree[root] = (tree[root] + c * (r - l + 1)) % p;
                label[root].add = (label[root].add + c) % p;
            }
            return;
        }
        pushDown(root, r - l + 1);
        int mid = (l + r) >> 1;
        if(L >= mid + 1) update(rson, L, R, tag, c);
        else if(R <= mid) update(lson, L, R, tag, c);
        else{
            update(lson, L, mid, tag, c); update(rson, mid + 1, R, tag, c);
        }
        pushUp(root);
    }
    long long query(int l, int r, int root, int L, int R)
    {
        if(L == l && R == r){
            return tree[root] % p;
        }
        pushDown(root, r - l + 1);
        int mid = (l + r) >> 1;
        if(L >= mid + 1) return (query(rson, L, R) % p);
        else if(R <= mid) return (query(lson, L, R) % p);
        else{
            return ((query(lson, L, mid) + query(rson, mid + 1, R)) % p);
        }
    }
    int main()
    {
        scanf("%d%d", &n, &p);
        build(1, n, 1);
        scanf("%d", &q);
        for(int cas = 1; cas <= q; cas++){
            int tag, t, g, c;
            scanf("%d", &tag);
            if(tag == 1){
                scanf("%d%d%d", &t, &g, &c);
                update(1, n, 1, t, g, 1, c);
            }
            else if(tag == 2){
                scanf("%d%d%d", &t, &g, &c);
                update(1, n, 1, t, g, 2, c);
            }
            else{
                scanf("%d%d", &t, &g);
                printf("%lld
    ", query(1, n, 1, t, g) % p);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Java_大数加法
    Java_找出最多的10个单词
    过滤文本敏感词
    JDK(Win10)下载与安装
    Agile PLM_统计物料消耗
    Java_扑克牌顺子
    Java8_stream_集合对象属性的合并
    Apache Maven下载与安装
    java泛型 无敌
    Java异常处理 无敌
  • 原文地址:https://www.cnblogs.com/solvit/p/11469385.html
Copyright © 2020-2023  润新知