[wikioi]线段树练习

http://codevs.cn/problem/1080/

#include <vector>
#include <iostream>
#include <string.h>

using namespace std;

const int MAXN = 100000;

struct Line {
    int left, right;
    int n;
};

Line tree[MAXN * 3];

void buildtr(int left, int right, int k) {
    tree[k].left = left;
    tree[k].right = right;
    tree[k].n = 0;
    if (left == right) return;
    int mid = (left + right) / 2;
    buildtr(left, mid, k * 2);
    buildtr(mid + 1, right, k * 2 + 1);
}

int query(int x, int k) {
    if (tree[k].left == x && tree[k].right == x) {
        return tree[k].n;
    }
    int mid = (tree[k].left + tree[k].right) / 2;
    if (x <= mid) return query(x, k * 2);
    else return query(x, k * 2 + 1);
}

int query(int l, int r, int k) {
    if (tree[k].left == l && tree[k].right == r) {
        //cout << "k:" << k << ",l" << l << "r," << r << ",n:" << tree[k].n << endl;
        return tree[k].n;
    }
    int mid = (tree[k].left + tree[k].right) / 2;
    if (r <= mid) {
        return query(l, r, k * 2);
    } else if (l > mid) {
        return query(l, r, k * 2 + 1);
    } else {
        return query(l, mid, k * 2) + query(mid + 1, r, k * 2 + 1);
    }
}

int update(int x, int y, int k) {
    int diff = 0;
    if (tree[k].left == x && tree[k].right == x) {
        diff = y - tree[k].n;
        tree[k].n = y;
        return diff;
    }
    int mid = (tree[k].left + tree[k].right) / 2;
    if (x <= mid) {
        diff = update(x, y, k * 2);
    } else {
        diff = update(x, y, k * 2 + 1);
    }
    tree[k].n += diff;
    return diff;
}

int add(int l, int r, int x, int k) {
    int diff = 0;
    if (tree[k].left == tree[k].right) {
        diff = x;
        tree[k].n += x;
        //cout << "diff:" << x << endl;
        return x;
    }
    int mid = (tree[k].left + tree[k].right) / 2;
    if (mid >= r) {
        diff = add(l, r, x, k * 2);
    } else if (mid < l) {
        diff = add(l, r, x, k * 2 + 1);
    } else {
        diff += add(l, mid, x, k * 2);
        diff += add(mid + 1, r, x, k * 2 + 1);
    }
    tree[k].n += diff;
    return diff;
}

int main() {
    int n;
    cin >> n;
    memset(tree, sizeof(tree), 0);
    buildtr(1, n, 1);
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        update(i, x, 1);
    }
    int m;
    cin >> m;
    while (m--) {
        int c, x, y;
        cin >> c >> x >> y;
        if (c == 1) {
            add(x, x, y, 1);
        } else if (c == 2) {
            int res = query(x, y, 1);
            cout << res << endl;
        }
    }
}

  

posted @ 2014-10-19 10:40  阿牧遥  阅读(200)  评论(0编辑  收藏  举报