A 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, ai, bi, hi,xi, yi (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;
}