zoj 3578 matrix

Matrix

Time Limit: 10 Seconds      Memory Limit: 131072 KB

N*M coordinate plane ((0, 0)~(n, m)). Initially the value of all N*M grids are 0.
An operation T(a, b, h, x, y) is defined as follow:
1. Select the maximum value in the matrix (x, y) ~ (x+a, y+b), suppose the maximum value is max
2. Change all the value in the matrix (x, y) ~ (x+a, y+b) into max+h
After C operations, please output the maximum value in the whole N*M coordinate.

Input

The input consists of several cases. 
For each case, the first line consists of three positive integers N , M and C (N ≤ 1000, M ≤ 1000, C ≤ 1000). In the following C lines, each line consists of 5 non-negative number, aibihi,xiyi (0 ≤ hi ≤ 10000, 0 ≤ xi < n, 0 ≤ yi < m).

Output

For each case, output the maximum height.

Sample Input

3 2 2
2 1 9 1 1
1 1 2 2 1

Sample Output

11


偷他的

http://kb.cnblogs.com/a/2369088/


#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

//#undef _DEBUG

#ifdef _DEBUG
#define debug_printf(...) printf(__VA_ARGS__)
#else
#define debug_printf(...)
#endif

struct HistoryBlock
{
    int a, b, x, y, h, H;

    bool crossesOverWith (const HistoryBlock &hb)
    {
        if (x + a <= hb.x || hb.x + hb.a <= x) {
            return false;
        } else if (y + b <= hb.y || hb.y + hb.b <= y) {
            return false;
        } else {
            return true;
        }
    }
};

const int MAXC = 1000;

int main (int argc, char **argv)
{
    HistoryBlock hb[MAXC];
    int c;
    int m;
    int n;

    while (scanf ("%d%d%d", &m, &n, &c) != EOF) {

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

            scanf ("%d%d%d%d%d", &hb[i].a, &hb[i].b, &hb[i].h, &hb[i].x, &hb[i].y);
            hb[i].H = 0;

            for (int k=0; k<i; ++k) {
                if (hb[k].crossesOverWith (hb[i])) {
                    hb[i].H = max (hb[i].H, hb[k].H);
                }
            }

            hb[i].H += hb[i].h;
        }

        int answer = 0;
        for (int i=0; i<c; ++i) {
            answer = max (answer, hb[i].H);
        }

        printf ("%d\n", answer);
    }

    return 0;
}



據說二維線段樹能過,下面的一維線段樹 + 枚舉TLE,傷心,貼着權當紀念吧


#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

#undef _DEBUG

#ifdef _DEBUG
#define debug_printf(...) printf(__VA_ARGS__)
#else
#define debug_printf(...) 0
#endif

struct Node
{
    int childMax;
  //  int left;
  //  int right;
    int value;
    bool valueDowned;

    Node (): childMax(0), /*left(0), right(0),*/value(0), valueDowned(false) {}
    Node (int cm,/* int lf, int rt,*/int v, bool vd): childMax(cm),/* left(lf), right(rt), */value(v), valueDowned(vd) {}
};

const int NODES_MAX = 2048;

struct SegmentTree
{
    Node node[NODES_MAX];

    void downValue (int left, int right, int nd)
    {
        assert (left < right);
        assert (0 < nd && nd < NODES_MAX);

        node[nd].valueDowned = true;
        node[nd].childMax = node[nd].value;

        if (left + 1 == right) {
            return;
        }

        node[nd + nd].valueDowned = false;
        node[nd + nd].value = node[nd].value;
        node[nd + nd].childMax = node[nd].value;

        node[nd + nd + 1].valueDowned = false;
        node[nd + nd + 1].value = node[nd].value;
        node[nd + nd + 1].childMax = node[nd].value;
    }

    int maxValue (int rangeLeft, int rangeRight, int left, int right, int nd)
    {
        if (rangeLeft <= left && right <= rangeRight) {
            return node[nd].childMax;
        } else if (rangeRight <= left || right <= rangeLeft) {
            return 0;
        }

        if (! node[nd].valueDowned) {
            downValue (left, right, nd);
        }

        if (left + 1 == right) {
            return node[nd].value;
        } else {
            assert (left < right);
        }

        int mid = (left + right) / 2;
        int leftMaxValue = maxValue (rangeLeft, rangeRight, left, mid, nd + nd);
        int rightMaxValue = maxValue (rangeLeft, rangeRight, mid, right, nd + nd + 1);

        if (leftMaxValue > rightMaxValue) {
            return leftMaxValue;
        } else {
            return rightMaxValue;
        }

        assert (false);
    }

    void setValue (int value, int rangeLeft, int rangeRight, int left, int right, int nd)
    {
        if (rangeLeft <= left && right <= rangeRight) {
            node[nd].value = value;
            node[nd].childMax = value;
            node[nd].valueDowned = false;
            return;
        } else if (rangeRight <= left || right <= rangeLeft) {
            return;
        }

        if (! node[nd].valueDowned) {
            downValue (left, right, nd);
        }

        if (left + 1 == right) {
            node[nd].value = value;
            node[nd].childMax = value;
            node[nd].valueDowned = true;
            return;
        } else {
            assert (left < right);
        }

        int mid = (left + right) / 2;
        setValue (value, rangeLeft, rangeRight, left, mid, nd + nd);
        setValue (value, rangeLeft, rangeRight, mid, right, nd + nd + 1);

        if (node[nd + nd].childMax > node[nd + nd + 1].childMax) {
            node[nd].childMax = node[nd + nd].childMax;
        } else {
            node[nd].childMax = node[nd + nd + 1].childMax;
        }

        node[nd].value = 0;
        node[nd].valueDowned = true;
    }

    void resetAll (int left, int right, int nd)
    {
        if (left + 1 == right) {
            node[nd].childMax = 0;
            node[nd].value = 0;
            node[nd].valueDowned = true;
            return;
        } else {
            assert (left < right);
        }

        int mid = (left + right) / 2;
        resetAll (left, mid, nd + nd);
        resetAll (mid, right, nd + nd + 1);

        if (node[nd + nd].childMax > node[nd + nd + 1].childMax) {
            node[nd].childMax = node[nd + nd].childMax;
        } else {
            node[nd].childMax = node[nd + nd + 1].childMax;
        }

        node[nd].value = 0;
        node[nd].valueDowned = true;
    }

    void print_tree (int left, int right, int nd)
    {
        if (left >= right) {
            return;
        }

        debug_printf ("node[%d]: left = %d, right = %d, value = %d, valueDowned = %d, childMax = %d\n",
            nd, left, right, node[nd].value, node[nd].valueDowned, node[nd].childMax);

        if (left + 1 == right) {
            return;
        } else {
            assert (left < right);
        }

        int mid = (left + right) / 2;
        print_tree (left, mid, nd + nd);
        print_tree (mid, right, nd + nd + 1);
    }
};

SegmentTree tree[1000];

int main (int argc, char **argv)
{
    int n, m, c;
    while (scanf ("%d%d%d", &m, &n, &c) == 3) {

        for (int i=0; i<m; ++i) {
            tree[i].resetAll (0, n, 1);

            //tree[i].print_tree (0, n, 1);
        }

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

            int a, b, h, x, y;
            scanf ("%d%d%d%d%d", &a, &b, &h, &x, &y);

            assert (0 < a && 0 < b);
            assert (0 <= x && 0 <= y);
            assert (x + a <= m && y + b <= n);

            int max = 0;
            for (int k=0; k<a; ++k) {
                int v = tree[x + k].maxValue (y, y + b, 0, n, 1);

                //tree[x + k].print_tree (0, n, 1);
                debug_printf ("maxValue = %d\n", v);

                if (v > max) {
                    max = v;
                }

                debug_printf ("max = %d\n", max);
            }

            for (int k=0; k<a; ++k) {
                tree[x + k].setValue (h + max, y, y + b, 0, n, 1);

                //tree[x + k].print_tree (0, n, 1);
            }
        }

        int max = 0;
        for (int i=0; i<m; ++i) {
            int v = tree[i].maxValue (0, n, 0, n, 1);
            if (v > max) {
                max = v;
            }
        }

        printf ("%d\n", max);
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章