[Luogu] 计数

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

#include <cstdio>
#include <iostream>

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

#define LL long long

LL W[N << 2], Min[N << 2], Size[N << 2], F[N << 2];
int n, T;
LL Answer;

#define gc getchar()
#define oo 999999999

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;
}

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

void Up(int jd) {
    W[jd] = W[lson] + W[rson];
    Min[jd] = min(Min[lson], Min[rson]);
    return ;
}

void Build_tree(int l, int r, int jd) {
    Size[jd] = (r - l + 1);
    if(l == r) {W[jd] = read(); Min[jd] = W[jd]; return ;}
    int mid = (l + r) >> 1;
    Build_tree(l, mid, lson);
    Build_tree(mid + 1, r, rson);
    Up(jd);
}

void Down(int jd) {
    int imp = F[jd];
    F[lson] += imp; F[rson] += imp;
    W[lson] += imp * Size[lson]; W[rson] += imp * Size[rson];
    Min[lson] += imp; Min[rson] += imp;
    F[jd] = 0;
    return ;
}

void Sec_A_min(int l, int r, int jd, int x, int y) {
    if(x <= l && r <= y) {Answer = min(Answer, Min[jd]); return ;}
    if(F[jd]) Down(jd);
    int mid = (l + r) >> 1;
    if(x <= mid) Sec_A_min(l, mid, lson, x, y);
    if(y > mid)  Sec_A_min(mid + 1, r, rson, x, y);
}

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

void Sec_G(int l, int r, int jd, int x, int y, int g) {
    if(x <= l && r <= y) {W[jd] += g * Size[jd]; Min[jd] += g; F[jd] += g; return ;}
    if(F[jd]) Down(jd);
    int mid = (l + r) >> 1;
    if(x <= mid) Sec_G(l, mid, lson, x, y, g);
    if(y > mid)  Sec_G(mid + 1, r, rson, x, y, g);
    Up(jd);
}

int main() {
    n = read(); T = read();
    Build_tree(1, n, 1);
    while(T --) {
        string s; cin >> s;
        if(s[0] == 'M') {Answer = oo; int x = read(), y = read(); Sec_A_min(1, n, 1, x, y); cout << Answer << "\n";}
        else if(s[0] == 'S') {Answer = 0; int x = read(), y = read(); Sec_A_sum(1, n, 1, x, y); cout << Answer << "\n";}
        else {int x = read(), y = read(), g = read(); Sec_G(1, n, 1, x, y, g);}
    }    
    return 0;
}

 

posted @ 2018-03-31 11:12  xayata  阅读(128)  评论(0编辑  收藏  举报