Codeforces 444C DZY Loves Colors(线段树)

题目大意:Codeforces 444C DZY Loves Colors

题目大意:两种操作,1是改动区间上l到r上面德值为x,2是询问l到r区间总的改动值。

解题思路:线段树模板题。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;
const int maxn = 5*1e5;
typedef long long ll;

ll s[maxn], del[maxn], mark[maxn];

void build (int u, int l, int r) {
    if (l < r) {
        int mid = (l + r)/2;
        build(u*2, l, mid);
        build(u*2+1, mid+1, r);
    } else
        mark[u] = l;
}

ll query (int u, int l, int r, int x, int y) {
    if (y < l || x > r)
        return 0;

    if (x <= l && r <= y)
        return s[u];

    int mid = (l + r) / 2;
    ll L = query(u*2, l, mid, x, y);
    ll R = query(u*2+1, mid+1, r, x, y);
    return L + R + max(0, min(r, y) - max(l, x) + 1) * del[u];
}

void clear (int u, int l, int r, int z) {
    if (mark[u]) {
        del[u] += abs(mark[u]-z);
        s[u] += 1LL * (r-l+1) * abs(mark[u]-z);
        mark[u] = 0;
    } else {

        if (l == r)
            return;

        int mid = (l + r) / 2, lc = u*2, rc = u*2+1;
        clear(lc, l, mid, z);
        clear(rc, mid+1, r, z);

        s[u] = s[lc] + s[rc] + 1LL * (r-l+1) * del[u];
    }
}

void modify (int u, int l, int r, int x, int y, int z) {
    //    printf("%d %d %d %d %d %d\n", u, l, r, x, y, z);
    if (y < l || x > r)
        return;

    if (x <= l && r <= y) {
        clear(u, l, r, z);
        mark[u] = z;
        return;
    }

    int mid = (l + r) / 2, lc = u*2, rc = u*2+1;
    if (mark[u]) {
        mark[lc] = mark[rc] = mark[u];
        mark[u] = 0;
    }
    modify(lc, l, mid, x, y, z);
    modify(rc, mid+1, r, x, y, z);
    s[u] = s[lc] + s[rc] + 1LL * (r-l+1) * del[u];
}

int main () {
    int n, m;
    scanf("%d%d", &n, &m);
    /*
       memset(sum, 0, sizeof(sum));
       memset(del, 0, sizeof(del));
       memset(mark, 0, sizeof(mark));
       */

    build(1, 1, n);

    int type, x, y, z;;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &type, &x, &y);
        if (type == 1) {
            scanf("%d", &z);
            modify(1, 1, n, x, y, z);
        } else
            printf("%lld\n", query(1, 1, n, x, y));
    }
    return 0;
}
posted @ 2016-04-01 08:33  lcchuguo  阅读(205)  评论(0编辑  收藏  举报