[Luogu] 维护序列

https://www.luogu.org/problemnew/show/P2023

线段树双懒标记下放

#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 10;

#define LL long long
#define lson jd << 1
#define rson jd << 1 | 1

LL w[N << 2], size[N << 2], fadd[N << 2], fmul[N << 2], Answer;
int n, Ty, Mod;

#define gc getchar()

inline int read() {
    int x = 0; char c = gc;
    while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
    return x;
} 

void Build_tree(int l, int r, int jd) {
    size[jd] = (r - l + 1); fmul[jd] = 1;
    if(l == r) {w[jd] = read(); w[jd] %= Mod; return ;}
    int mid = (l + r) >> 1;
    Build_tree(l, mid, lson);
    Build_tree(mid + 1, r, rson);
    w[jd] = (w[lson] + w[rson]) % Mod;
}

void Down(int jd) {
    if(!fadd[jd] && fmul[jd] == 1) return ;
    w[lson] = w[lson] * fmul[jd] % Mod;
    w[rson] = w[rson] * fmul[jd] % Mod;
    w[lson] = w[lson] + fadd[jd] * size[lson] % Mod;
    w[rson] = w[rson] + fadd[jd] * size[rson] % Mod;
    fadd[lson] = (fadd[lson] * fmul[jd] + fadd[jd]) % Mod;
    fadd[rson] = (fadd[rson] * fmul[jd] + fadd[jd]) % Mod;
    fmul[lson] = fmul[lson] * fmul[jd] % Mod;
    fmul[rson] = fmul[rson] * fmul[jd] % Mod;
    fadd[jd] = 0;
    fmul[jd] = 1;
}

void Sec_G_mul(int l, int r, int jd, int x, int y, int imp) {
    if(x <= l && r <= y) {
        w[jd] = (w[jd] * imp) % Mod;
        fmul[jd] = (fmul[jd] * imp) % Mod;
        fadd[jd] = (fadd[jd] * imp) % Mod;
        return ;
    }
    Down(jd); 
    int mid = (l + r) >> 1;
    if(x <= mid) Sec_G_mul(l, mid, lson, x, y, imp);
    if(y > mid)  Sec_G_mul(mid + 1, r, rson, x, y, imp);
    w[jd] = (w[lson] + w[rson]) % Mod;
}

void Sec_G_add(int l, int r, int jd, int x, int y, int k) {
    if(x <= l && r <= y) {
        w[jd] = (w[jd] + size[jd] * k) % Mod;
        fadd[jd] = (fadd[jd] + k) % Mod;
        return ;
    }
    Down(jd);
    int mid = (l + r) >> 1;
    if(x <= mid) Sec_G_add(l, mid, lson, x, y, k);
    if(y > mid)  Sec_G_add(mid + 1, r, rson, x, y, k);
    w[jd] = (w[lson] + w[rson]) % Mod; 
}

void Sec_A(int l, int r, int jd, int x, int y) {
    if(x <= l && r <= y) {
        Answer += w[jd];
        if(Answer >= Mod) Answer %= Mod;
        return ;
    }
    Down(jd);
    int mid = (l + r) >> 1;
    if(x <= mid) Sec_A(l, mid, lson, x, y);
    if(y > mid)  Sec_A(mid + 1, r, rson, x, y);
} 

int main() {
    n = read(); Mod = read();
    Build_tree(1, n, 1);
       Ty = read();
    while(Ty --) {
        int opt = read();
        if(opt == 1) {
            int x = read(), y = read(), k = read(); k %= Mod;
            Sec_G_mul(1, n, 1, x, y, k);
        } else if(opt == 2) {
            int x = read(), y = read(), k = read(); k %= Mod;
            Sec_G_add(1, n, 1, x, y, k); 
        } else {
            int x = read(), y = read();
            Answer = 0;
            Sec_A(1, n, 1, x, y);
            cout << Answer << endl; 
        }
    }    
    return 0;
}
/*
5 38
5 4 2 3
1 4 1
2 5
2 4 2
3 5 5
1 4
*/

 

posted @ 2018-03-27 16:08  xayata  阅读(438)  评论(0编辑  收藏  举报