Problem p00432 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cstdio>
#include <utility>
#include <vector>

using namespace std;

int n;
short min_x1, max_x2, min_y1, max_y2;
vector<pair<pair<short, short>, short>> *variation;
int surface_sum;
int perimeter_sum;
vector<pair<pair<short, short>, short>>::iterator save_variation;

bool Comp(const pair<pair<short, short>, short> &a,
          const pair<pair<short, short>, short> &b) {
  pair<short, short> axy = a.first;
  pair<short, short> bxy = b.first;

  if (axy.second == bxy.second) {
    return axy.first < bxy.first;
  } else {
    return axy.second < bxy.second;
  }

  return false;
}

void sort_vector() {
  sort(variation->begin(), variation->end(), Comp);
  return;
}

short variation_return(short x, short y) {
  short sum = 0;

  if (save_variation == variation->end())
    return 0;

  while ((save_variation->first.second < y) ||
         ((save_variation->first.second == y) &&
          (save_variation->first.first < x))) {
    save_variation++;
    if (save_variation == variation->end())
      return 0;
  }

  while (save_variation->first.first == x &&
         save_variation->first.second == y) {
    sum += save_variation->second;
    save_variation++;
    if (save_variation == variation->end())
      return sum;
  }

  return sum;
}

void surface(short calc[2][10002], int j) {
  if (calc[1][j] > 0)
    surface_sum++;

  return;
}

void perimeter(short calc[2][10002], int j) {
  if (calc[1][j] + calc[1][j - 1] > 0 &&
      (calc[1][j] == 0 || calc[1][j - 1] == 0))
    perimeter_sum++;

  if (calc[1][j] + calc[0][j] > 0 && (calc[1][j] == 0 || calc[0][j] == 0))
    perimeter_sum++;

  return;
}

void process() {
  short i;
  short calc[2][10002];

  for (i = 0; i < 2; i++) {
    int j;
    for (j = 0; j < 10002; j++) {
      calc[i][j] = 0;
    }
  }

  for (i = min_y1 - 1; i < max_y2 + 1; i++) {
    int j;

    for (j = min_x1 - 1; j < max_x2 + 1; j++) {
      short x = variation_return(j, i);
      calc[1][j] = x;

      calc[1][j] += calc[1][j - 1];
      calc[1][j] += calc[0][j];
      calc[1][j] -= calc[0][j - 1];
      surface(calc, j);
      perimeter(calc, j);

      if (j > min_x1 + 1) {
        calc[0][j - 3] = calc[1][j - 3];
      }
    }

    calc[0][max_x2 - 2] = calc[1][max_x2 - 2];
    calc[0][max_x2 - 1] = calc[1][max_x2 - 1];
    calc[0][max_x2] = calc[1][max_x2];
  }
  return;
}

int main() {
  while (1) {
    short i;
    int r;
    short x1, x2, y1, y2;

    scanf("%d %d", &n, &r);
    if (n == 0 && r == 0)
      return 0;

    variation = new vector<pair<pair<short, short>, short>>();

    min_x1 = 10000;
    min_y1 = 10000;
    max_x2 = 0;
    max_y2 = 0;
    for (i = 0; i < n; i++) {
      scanf("%hd %hd %hd %hd", &x1, &y1, &x2, &y2);
      x1++;
      x2++;
      y1++;
      y2++;
      if (min_x1 > x1)
        min_x1 = x1;
      if (max_x2 < x2)
        max_x2 = x2;
      if (min_y1 > y1)
        min_y1 = y1;
      if (max_y2 < y2)
        max_y2 = y2;
      variation->push_back(make_pair(make_pair(x1, y1), 1));
      variation->push_back(make_pair(make_pair(x1, y2), -1));
      variation->push_back(make_pair(make_pair(x2, y1), -1));
      variation->push_back(make_pair(make_pair(x2, y2), 1));
    }
    surface_sum = 0;
    perimeter_sum = 0;

    sort_vector();

    save_variation = variation->begin();

    process();

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

    if (r == 2) {
      printf("%d\\n", perimeter_sum);
    }

    delete variation;
  }
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <map>
#include <utility>

using namespace std;

int n;
short min_x1, max_x2, min_y1, max_y2;
short x1, x2, y1, y2;
map<pair<short, short>, short> *variation;
int surface_sum;
int perimeter_sum;

void variation_inc(short x, short y) {
  short value;
  map<pair<short, short>, short>::iterator location;

  location = variation->find(make_pair(x, y));
  if (location != variation->end()) {
    value = location->second + 1;
  } else {
    value = 1;
  }

  variation->erase(make_pair(x, y));

  if (value != 0) {
    variation->insert(pair<pair<short, short>, short>(make_pair(x, y), value));
  }

  return;
}

void variation_dec(short x, short y) {
  short value;
  map<pair<short, short>, short>::iterator location;

  location = variation->find(make_pair(x, y));
  if (location != variation->end()) {
    value = location->second - 1;
  } else {
    value = -1;
  }

  variation->erase(make_pair(x, y));

  if (value != 0) {
    variation->insert(pair<pair<short, short>, short>(make_pair(x, y), value));
  }

  return;
}

short variation_return(short x, short y) {
  short value;
  map<pair<short, short>, short>::iterator location;

  location = variation->find(make_pair(x, y));
  if (location != variation->end()) {
    value = location->second;
  } else {
    value = 0;
  }

  return value;
}

void surface(short calc[2][10002], int j) {
  if (calc[1][j] > 0)
    surface_sum++;

  return;
}

void perimeter(short calc[2][10002], int j) {
  if (calc[1][j] + calc[1][j - 1] > 0 &&
      (calc[1][j] == 0 || calc[1][j - 1] == 0))
    perimeter_sum++;

  if (calc[1][j] + calc[0][j] > 0 && (calc[1][j] == 0 || calc[0][j] == 0))
    perimeter_sum++;

  return;
}
void process() {
  short i;
  short calc[2][10002];

  for (i = 0; i < 2; i++) {
    int j;
    for (j = 0; j < 10002; j++) {
      calc[i][j] = 0;
    }
  }

  for (i = min_y1 - 1; i < max_y2 + 1; i++) {
    int j;

    for (j = min_x1 - 1; j < max_x2 + 1; j++) {
      calc[1][j] = variation_return(j, i);

      calc[1][j] += calc[1][j - 1];
      calc[1][j] += calc[0][j];
      calc[1][j] -= calc[0][j - 1];
    }

    for (j = min_x1; j < max_x2 + 1; j++) {
      surface(calc, j);
      perimeter(calc, j);
      calc[0][j] = calc[1][j];
    }
  }

  return;
}

int main() {
  while (1) {
    short i;
    int r;

    scanf("%d %d", &n, &r);
    if (n == 0 && r == 0)
      return 0;

    variation = new map<pair<short, short>, short>();

    min_x1 = 10000;
    min_y1 = 10000;
    max_x2 = 0;
    max_y2 = 0;
    for (i = 0; i < n; i++) {
      scanf("%hd %hd %hd %hd", &x1, &y1, &x2, &y2);
      x1++;
      x2++;
      y1++;
      y2++;
      if (min_x1 > x1)
        min_x1 = x1;
      if (max_x2 < x2)
        max_x2 = x2;
      if (min_y1 > y1)
        min_y1 = y1;
      if (max_y2 < y2)
        max_y2 = y2;
      variation_inc(x1, y1);
      variation_dec(x1, y2);
      variation_dec(x2, y1);
      variation_inc(x2, y2);
    }
    surface_sum = 0;
    perimeter_sum = 0;

    process();

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

    if (r == 2) {
      printf("%d\\n", perimeter_sum);
    }

    delete variation;
  }
}