zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    PHP+JQUEY+AJAX实现分页
    Flume知识扩展
    Flume高级之自定义MySQLSource
    Flume监控之Ganglia
    Flume 概述/企业案例
    Yarn (转自之乎者也)
    MapReduce如何解决数据倾斜?
    JVM调优
    Hive性能优化
    HBase的二级索引
  • 原文地址:https://www.cnblogs.com/moonbay/p/2749579.html
Copyright © 2011-2022 走看看