• P2023 [AHOI2009]维护序列


    线段树模板题

    此题关键在于 pushdown

    考虑加法标记 lt1 和 乘法标记 lt2

    考虑到乘法优先级 要 高于 加法优先级

    因此在 pushdown 里先 传 lt2 再传 lt1

    注意 lt2 传的时候,两个儿子的 lt1 也都要乘上 lt2

    code:

    #include <bits/stdc++.h>
    #define int long long 
    using namespace std;
    const int N = 100005;
    int n, m, P, a[N], maxid = -1, Ans1[N], Ans2[N], cnt = 0;
    
    template <typename T>
    inline void read(T &t) {
        t = 0; T m = 1; char ch = getchar();
        while(ch < '0' || ch > '9') { if(ch == '-') m = -1; ch = getchar(); }
        while(ch >= '0' && ch <= '9') { t = (t << 3) + (t << 1) + (ch & 15); ch = getchar(); }
        t *= m;
    } 
    struct Stree {
        int l, r, sum, lt1, lt2;
    }tree[N << 4];
    
    void pushdown(int rt) {
        int l1 = tree[rt].lt1, l2 = tree[rt].lt2;
        tree[rt << 1].lt2 *= l2, tree[rt << 1].lt2 %= P;
        tree[rt << 1 | 1].lt2 *= l2, tree[rt << 1 | 1].lt2 %= P;
        tree[rt << 1].lt1 *= l2, tree[rt << 1].lt1 %= P;
        tree[rt << 1 | 1].lt1 *= l2, tree[rt << 1 | 1].lt1 %= P;
        tree[rt << 1].sum *= l2, tree[rt << 1].sum %= P;
        tree[rt << 1 | 1].sum *= l2, tree[rt << 1 | 1].sum %= P;
        tree[rt].lt2 = 1;
        tree[rt << 1].lt1 += l1, tree[rt << 1].lt1 %= P;
        tree[rt << 1 | 1].lt1 += l1, tree[rt << 1 | 1].lt1 %= P;
        tree[rt << 1].sum += (tree[rt << 1].r - tree[rt << 1].l + 1) * l1, tree[rt << 1].sum %= P;
        tree[rt << 1 | 1].sum += (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l + 1) * l1, tree[rt << 1 | 1].sum %= P;
        tree[rt].lt1 = 0;	 
    }
    
    // Checked
    void pushup(int rt) {
        tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum; tree[rt].sum %= P;
    }
    
    // Checked
    void build(int l, int r, int rt) {
        tree[rt].l = l, tree[rt].r = r, tree[rt].lt1 = 0, tree[rt].lt2 = 1;
        if(l == r) { tree[rt].sum = a[l]; tree[rt].sum %= P; return; }
        int mid = (l + r) >> 1;
        build(l, mid, rt << 1), build(mid + 1, r, rt << 1 | 1);
        pushup(rt); 
    }
    
    int Quary(int L, int R, int l, int r, int rt) {
        if(L <= l && r <= R) return tree[rt].sum;
        if(tree[rt].lt1 != 0 || tree[rt].lt2 != 1) pushdown(rt);
        int ans = 0, mid = (l + r) >> 1;
        if(L <= mid) ans += Quary(L, R, l, mid, rt << 1);
        if(R > mid) ans += Quary(L, R, mid + 1, r, rt << 1 | 1); 
        return ans;
    }
     
    void upd1(int L, int R, int C, int l, int r, int rt) {
        if(L <= l && r <= R) {
            tree[rt].sum += (r - l + 1) * C; tree[rt].sum %= P;
            tree[rt].lt1 += C; tree[rt].lt1 %= P; return;
        }
        if(tree[rt].lt1 != 0 || tree[rt].lt2 != 1) pushdown(rt);
        int mid = (l + r) >> 1;
        if(L <= mid) upd1(L, R, C, l, mid, rt << 1);
        if(R > mid) upd1(L, R, C, mid + 1, r, rt << 1 | 1);
        pushup(rt); 
    }
    
    void upd2(int L, int R, int C, int l, int r, int rt) {
        if(L <= l && r <= R) {
            tree[rt].sum *= C; tree[rt].sum %= P;
            tree[rt].lt1 *= C; tree[rt].lt1 %= P;
            tree[rt].lt2 *= C; tree[rt].lt2 %= P; return;
        }
        if(tree[rt].lt1 != 0 || tree[rt].lt2 != 1) pushdown(rt);
        int mid = (l + r) >> 1;
        if(L <= mid) upd2(L, R, C, l, mid, rt << 1);
        if(R > mid) upd2(L, R, C, mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    
    signed main() {
        read(n), read(P);
        for(int i = 1; i <= n; i++) {
            read(a[i]);
        }
        build(1, n, 1);
        read(m);
        for(int i = 1; i <= m; i++) {
            int opt; read(opt);
            if(opt == 1) {
                int x, y, z; read(x), read(y), read(z);
                upd2(x, y, z, 1, n, 1);
            }
            if(opt == 2) {
                int x, y, z; read(x), read(y), read(z);
                upd1(x, y, z, 1, n, 1);
            }
            if(opt == 3) {
                int x, y; read(x), read(y);
                printf("%lld
    ", Quary(x, y, 1, n, 1) % P);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    SpringBoot整合jsp
    SpringBoot常用application.properties配置
    SpringBoot入门
    vue cli创建vue项目
    vue 指令
    vue hello
    pytest doc
    atom
    java csvutil
    Django uuidfield 实现自动生成唯一列,并设置为主键
  • 原文地址:https://www.cnblogs.com/chloristendika/p/10101925.html
Copyright © 2020-2023  润新知