hdu 1892二维树状数组

这题我知道是用树状数组,可是好久没打树状数组了,就想用普通方法水过去~~结果……结果……水了好多方法都水不过,出题人真狠呐……我的水方法是对于每一次查询,初始化ans=(x2-x1+1)*(y2-y1+1),然后对于这个操作之前的每一个操作,对ans进行处理即可。可是交上去TLE,加上输入外挂,还是TLE,又加一个优化,即对于每一个查询,如果查询的区间小于10000,就直接数,还是TLE,服了,还是打树状数组吧~~~~~~~~~~~~~


我的水代码:

/*

 * hdu1892/win.cpp

 * Created on: 2012-11-1

 * Author    : ben

 */

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <ctime>

#include <iostream>

#include <algorithm>

#include <queue>

#include <set>

#include <map>

#include <stack>

#include <string>

#include <vector>

#include <deque>

#include <list>

#include <functional>

#include <numeric>

#include <cctype>

using namespace std;

const int MAXN = 1010;

typedef struct Ope{

    int x1, x2, y1, y2;

    int n;

    char type;

}Ope;

vector<Ope> ope;

int room[MAXN][MAXN];

inline int get_int() {

    int res = 0, ch;

    while (!((ch = getchar()) >= '0' && ch <= '9')) {

        if (ch == EOF)

            return 1 << 30;

    }

    res = ch - '0';

    while ((ch = getchar()) >= '0' && ch <= '9')

        res = res * 10 + (ch - '0');

    return res;

}

inline bool inrect(int &x, int &y, int &x1, int &y1, int &x2, int &y2) {

    return x >= x1 && x <= x2 && y >= y1 && y <= y2;

}

void work2(int x1, int y1, int x2, int y2, int n) {

    int ans = (x2 - x1 + 1) * (y2 - y1 + 1);

    for(int i = 0; i < n; i++) {

        if(ope[i].type == 'M') {

            if(inrect(ope[i].x1, ope[i].y1, x1, y1, x2, y2)) {

                ans -= ope[i].n;

            }

            if(inrect(ope[i].x2, ope[i].y2, x1, y1, x2, y2)) {

                ans += ope[i].n;

            }

        }else if(ope[i].type == 'A') {

            if(inrect(ope[i].x1, ope[i].y1, x1, y1, x2, y2)) {

                ans += ope[i].n;

            }

        }else if(ope[i].type == 'D') {

            if(inrect(ope[i].x1, ope[i].y1, x1, y1, x2, y2)) {

                ans -= ope[i].n;

            }

        }

    }

    printf("%d\n", ans);

}

void work1(Ope &o) {

    int ans = (o.x2 - o.x1 + 1) * (o.y2 - o.y1 + 1);

    if(ans < 1000) {

        ans = 0;

        for(int i = o.x1; i <= o.x2; i++) {

            for(int j = o.y1; j <= o.y2; j++) {

                ans += room[i][j];

            }

        }

        printf("%d\n", ans);

        o.type = 0;

    }

}

inline void input(Ope &o) {

    char c = getchar();

    int x1, y1, x2, y2;

    while(c <= ' ') {

        c = getchar();

    }

    o.type = c;

    if(c == 'S') {

        x1 = get_int(), y1 = get_int(), x2 = get_int(), y2 = get_int();

        o.x1 = min(x1, x2); o.x2 = max(x1, x2);

        o.y1 = min(y1, y2); o.y2 = max(y1, y2);

        work1(o);

    }else if(c == 'A') {

        o.x1 = get_int(), o.y1 = get_int(),    o.n = get_int();

        room[o.x1][o.y1] += o.n;

    }else if(c == 'D') {

        o.x1 = get_int(), o.y1 = get_int(), o.n = get_int();

        if(room[o.x1][o.y1] < o.n) {

            o.n = room[o.x1][o.y1];

        }

        room[o.x1][o.y1] -= o.n;

    }else  if(c == 'M') {

        o.x1 = get_int(), o.y1 = get_int(), o.x2 = get_int(), o.y2 = get_int();

        o.n = get_int();

        if(room[o.x1][o.y1] < o.n) {

            o.n = room[o.x1][o.y1];

        }

        room[o.x1][o.y1] -= o.n;

        room[o.x2][o.y2] += o.n;

    }

}



int main() {

#ifndef ONLINE_JUDGE

    freopen("data.in", "r", stdin);

#endif

    int T, Q;

    T = get_int();

    for(int t = 1; t <= T; t++) {

        printf("Case %d:\n", t);

        Q = get_int();

        fill(*room, *room + MAXN * MAXN, 1);

        ope.resize(Q);

        for_each(ope.begin(), ope.end(), input);

        for(int i = 0, len = (int)ope.size(); i < len; i++) {

            if(ope[i].type == 'S') {

                work2(ope[i].x1, ope[i].y1, ope[i].x2, ope[i].y2, i);

            }

        }

    }

    return 0;

}

 

二维树状数组代码:

/*

 * hdu1892/win.cpp

 * Created on: 2011-9-6

 * Author    : ben

 */

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <map>

using namespace std;

typedef long long LL;

const int MAXN = 1005;

LL data[MAXN][MAXN];

int Row = 1001, Col = 1001;

inline int Lowbit(const int &x) { // x > 0

    return x & (-x);

}

LL sum(int x, int y) {

    LL ret = 0;

    for(int i = x; i > 0; i -= Lowbit(i)) {

        for(int j = y; j > 0; j -= Lowbit(j)) {

            ret += data[i][j];

        }

    }

    return ret;

}

void update(int x, int y, int delta) {

    for(int i = x; i <= Row; i += Lowbit(i)) {

        for(int j = y; j <= Col; j += Lowbit(j)) {

            data[i][j] += delta;

        }

    }

}

void work() {

    char c;

    int x1, y1, x2, y2, n;

    scanf(" %c", &c);

    if(c == 'S') {

        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);

        if(x1 > x2) {

            swap(x1, x2);

        }

        if(y1 > y2) {

            swap(y1, y2);

        }

        printf("%d\n", (int)(sum(x2 + 1, y2 + 1) - sum(x1, y2 + 1) + sum(x1, y1) - sum(x2 + 1, y1)));

    }else if(c == 'A') {

        scanf("%d%d%d", &x1, &y1, &n);

        update(x1 + 1, y1 + 1, n);

    }else if(c == 'D') {

        scanf("%d%d%d", &x1, &y1, &n);

        x1++, y1++;

        int t =sum(x1, y1) - sum(x1 - 1, y1) - sum(x1, y1 - 1) + sum(x1 - 1, y1 - 1);

        if(t < n) {

            n = t;

        }

        update(x1, y1, -n);

    }else if(c == 'M') {

        scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &n);

        x1++, y1++;

        x2++, y2++;

        int t =sum(x1, y1) - sum(x1 - 1, y1) - sum(x1, y1 - 1) + sum(x1 - 1, y1 - 1);

        if(t < n) {

            n = t;

        }

        update(x1, y1, -n);

        update(x2, y2, n);

    }

}

void init() {

    for(int i = 1; i <= Row; i++) {

        for(int j = 1; j <= Col; j++) {

            update(i, j, 1);

        }

    }

}

int main() {

#ifndef ONLINE_JUDGE

    freopen("data.in", "r", stdin);

#endif

    int T, Q;

    scanf("%d", &T);

    for(int t = 1; t <= T; t++) {

        printf("Case %d:\n", t);

        scanf("%d", &Q);

        fill(*data, *data + MAXN * MAXN, 0);

        init();

        while(Q--) {

            work();

        }

    }

    return 0;

}

你可能感兴趣的:(树状数组)