Problem p04002 (C++)

Buggy submission (status: Runtime Error):


#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;

template <class T> class splay {
private:
  struct node {
    node *L, *R;
    T key;
    node() {
      L = NULL;
      R = NULL;
    }
    node(const T a) {
      key = a;
      L = NULL;
      R = NULL;
    }
  };
  node *root;
  node *path[100]; // depth can't be more than 30 ?
  int iter;
  inline bool getpath(const T a) {
    iter = 0;
    if (root == NULL) {
      return false;
    }
    node *cur = root;
    path[iter++] = cur;
    while (cur->key != a) {
      if (cur->key > a)
        cur = cur->L;
      else
        cur = cur->R;
      if (cur == NULL)
        return false;
      path[iter++] = cur;
    }
    return true;
  }
  inline void Getpath(const T a) {
    iter = 0;
    if (root == NULL) {
      root = new node(a);
      path[iter++] = root;
      return;
    }
    node *cur = root;
    path[iter++] = cur;
    while (cur->key != a) {
      if (cur->key > a)
        if (cur->L == NULL) {
          cur->L = new node(a);
          path[iter++] = cur->L;
          return;
        } else
          cur = cur->L;
      else if (cur->R == NULL) {
        cur->R = new node(a);
        path[iter++] = cur->R;
        return;
      } else
        cur = cur->R;
      path[iter++] = cur;
    }
  }
  void Splay() {
    int i = iter - 1;
    root = path[i];
    for (; i > 2;) {
      i -= 2;
      if (path[i]->L == path[i + 1])
        if (path[i + 1]->L == path[i + 2]) {
          bool leftish = (path[i - 1]->L == path[i]);

          path[i]->L = path[i + 1]->R;
          path[i + 1]->R = path[i];
          path[i + 1]->L = path[i + 2]->R;
          path[i + 2]->R = path[i + 1];

          swap(path[i + 2], path[i]);
          if (leftish)
            path[i - 1]->L = path[i];
          else
            path[i - 1]->R = path[i];
        } else {
          bool leftish = (path[i - 1]->L == path[i]);

          path[i]->L = path[i + 2]->R;
          path[i + 1]->R = path[i + 2]->L;
          path[i + 2]->L = path[i + 1];
          path[i + 2]->R = path[i];

          swap(path[i + 2], path[i]);
          if (leftish)
            path[i - 1]->L = path[i];
          else
            path[i - 1]->R = path[i];
        }
      else if (path[i + 1]->L == path[i + 2]) {
        bool leftish = (path[i - 1]->L == path[i]);

        path[i]->R = path[i + 2]->L;
        path[i + 1]->L = path[i + 2]->R;
        path[i + 2]->R = path[i + 1];
        path[i + 2]->L = path[i];

        swap(path[i + 2], path[i]);
        if (leftish)
          path[i - 1]->L = path[i];
        else
          path[i - 1]->R = path[i];
      } else {
        bool leftish = (path[i - 1]->L == path[i]);

        path[i]->R = path[i + 1]->L;
        path[i + 1]->L = path[i];
        path[i + 1]->R = path[i + 2]->L;
        path[i + 2]->L = path[i + 1];

        swap(path[i + 2], path[i]);
        if (leftish)
          path[i - 1]->L = path[i];
        else
          path[i - 1]->R = path[i];
      }
    }

    if (i == 2) {
      i -= 2;
      if (path[i]->L == path[i + 1])
        if (path[i + 1]->L == path[i + 2]) {
          path[i]->L = path[i + 1]->R;
          path[i + 1]->R = path[i];
          path[i + 1]->L = path[i + 2]->R;
          path[i + 2]->R = path[i + 1];
        } else {
          path[i]->L = path[i + 2]->R;
          path[i + 1]->R = path[i + 2]->L;
          path[i + 2]->L = path[i + 1];
          path[i + 2]->R = path[i];
        }
      else if (path[i + 1]->L == path[i + 2]) {
        path[i]->R = path[i + 2]->L;
        path[i + 1]->L = path[i + 2]->R;
        path[i + 2]->R = path[i + 1];
        path[i + 2]->L = path[i];
      } else {
        path[i]->R = path[i + 1]->L;
        path[i + 1]->L = path[i];
        path[i + 1]->R = path[i + 2]->L;
        path[i + 2]->L = path[i + 1];
      }
    }

    if (i == 1) {
      i = 0;
      if (path[0]->L == path[1]) {
        path[0]->L = path[1]->R;
        path[1]->R = path[0];
      } else {
        path[0]->R = path[1]->L;
        path[1]->L = path[0];
      }
    }
  }

public:
  bool empty() { return (root == NULL); }
  T extractmin() {
    node *c1 = root, *c2 = root->L;
    if (c2 == NULL) {
      T val = root->key;
      root = root->R;
      return val;
    } else {
      while (c2->L != NULL)
        c2 = c2->L, c1 = c1->L;
      c1->L = c2->R;
      return c2->key;
    }
  }
  splay() { root = NULL; }
  void insert(const T x) {
    Getpath(x);
    Splay();
  }
  bool check(const T x) {
    bool res = getpath(x);
    if (res) {
      Splay();
      return true;
    }
    return false;
  }
  void erase(const T x) {
    if (!getpath(x))
      return;
    if (path[iter - 1]->R != NULL) {
      path[iter] = path[iter - 1]->R;
      ++iter;
      while (path[iter - 1]->L != NULL) {
        path[iter] = path[iter - 1]->L;
        ++iter;
      }
      Splay();
      getpath(x);
      Splay();
      root->R->L = root->L;
      root = root->R;
      return;
    }
    for (int i = iter - 2; i >= 0; --i) {
      if (path[i + 1] != path[i]->R) {
        iter = i + 1;
        Splay();
        getpath(x);
        Splay();
        root->R->L = root->L;
        root = root->R;
        return;
      }
    }
    Splay();
    root = root->L;
  }
};

splay<pair<int, int>> s;
splay<pair<int, int>> checked;
int cnt[10];
namespace fastinput {
/** Interface */

inline int readChar();
template <class T = int> inline T readInt();
template <class T> inline void writeInt(T x, char end = 0);
inline void writeChar(int x);
inline void writeWord(const char *s);

/** Read */

static const int buf_size = 16384;

inline int getChar() {
  static char buf[buf_size];
  static int len = 0, pos = 0;
  if (pos == len)
    pos = 0, len = fread(buf, 1, buf_size, stdin);
  if (pos == len)
    return -1;
  return buf[pos++];
}

inline int readChar() {
  int c = getChar();
  while (c <= 32)
    c = getChar();
  return c;
}

template <class T> inline T readInt() {
  int s = 1, c = readChar();
  T x = 0;
  if (c == '-')
    s = -1, c = getChar();
  while ('0' <= c && c <= '9')
    x = x * 10 + c - '0', c = getChar();
  return s == 1 ? x : -x;
}

/** Write */

static int write_pos = 0;
static char write_buf[buf_size];

inline void writeChar(int x) {
  if (write_pos == buf_size)
    fwrite(write_buf, 1, buf_size, stdout), write_pos = 0;
  write_buf[write_pos++] = x;
}

template <class T> inline void writeInt(T x, char end) {
  if (x < 0)
    writeChar('-'), x = -x;

  char s[24];
  int n = 0;
  while (x || !n)
    s[n++] = '0' + x % 10, x /= 10;
  while (n--)
    writeChar(s[n]);
  if (end)
    writeChar(end);
}

inline void writeWord(const char *s) {
  while (*s)
    writeChar(*s++);
}

struct Flusher {
  ~Flusher() {
    if (write_pos)
      fwrite(write_buf, 1, write_pos, stdout), write_pos = 0;
  }
} flusher;
} // namespace fastinput

using namespace fastinput;

int main() {
  ::ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  int h = readInt(), w = readInt(), n = readInt();
  vector<pair<int, int>> v(n);
  for (int i = 0; i < n; ++i) {
    int x = readInt();
    int y = readInt();
    --x, --y;
    s.insert({x, y});
    v[i] = {x, y};
  }
  for (auto lr : v) {
    int x = lr.first;
    int y = lr.second;
    for (int i = max(0, x - 2); i <= x && i + 2 < h; ++i)
      for (int j = max(0, y - 2); j <= y && j + 2 < w; ++j) {
        if (checked.check({i, j}))
          continue;
        int cntsum = 0;
        for (int x1 = i; x1 <= i + 2; ++x1)
          for (int y1 = j; y1 <= j + 2; ++y1)
            cntsum += s.check({x1, y1});
        checked.insert({i, j});
        ++cnt[cntsum];
      }
  }

  int sum = 0;
  for (int i = 1; i <= 9; ++i)
    sum += cnt[i];

  cout << (h - 2LL) * (w - 2LL) - sum << "\n";
  for (int i = 1; i <= 9; ++i)
    cout << cnt[i] << "\n";

  return 0;
}

Fixed submission:


#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;

template <class T> class splay {
private:
  struct node {
    node *L, *R;
    T key;
    node() {
      L = NULL;
      R = NULL;
    }
    node(const T a) {
      key = a;
      L = NULL;
      R = NULL;
    }
  };
  node *root;
  node *path[10000]; // depth can't be more than 30 ?
  int iter;
  inline bool getpath(const T a) {
    iter = 0;
    if (root == NULL) {
      return false;
    }
    node *cur = root;
    path[iter++] = cur;
    while (cur->key != a) {
      if (cur->key > a)
        cur = cur->L;
      else
        cur = cur->R;
      if (cur == NULL)
        return false;
      path[iter++] = cur;
    }
    return true;
  }
  inline void Getpath(const T a) {
    iter = 0;
    if (root == NULL) {
      root = new node(a);
      path[iter++] = root;
      return;
    }
    node *cur = root;
    path[iter++] = cur;
    while (cur->key != a) {
      if (cur->key > a)
        if (cur->L == NULL) {
          cur->L = new node(a);
          path[iter++] = cur->L;
          return;
        } else
          cur = cur->L;
      else if (cur->R == NULL) {
        cur->R = new node(a);
        path[iter++] = cur->R;
        return;
      } else
        cur = cur->R;
      path[iter++] = cur;
    }
  }
  void Splay() {
    int i = iter - 1;
    root = path[i];
    for (; i > 2;) {
      i -= 2;
      if (path[i]->L == path[i + 1])
        if (path[i + 1]->L == path[i + 2]) {
          bool leftish = (path[i - 1]->L == path[i]);

          path[i]->L = path[i + 1]->R;
          path[i + 1]->R = path[i];
          path[i + 1]->L = path[i + 2]->R;
          path[i + 2]->R = path[i + 1];

          swap(path[i + 2], path[i]);
          if (leftish)
            path[i - 1]->L = path[i];
          else
            path[i - 1]->R = path[i];
        } else {
          bool leftish = (path[i - 1]->L == path[i]);

          path[i]->L = path[i + 2]->R;
          path[i + 1]->R = path[i + 2]->L;
          path[i + 2]->L = path[i + 1];
          path[i + 2]->R = path[i];

          swap(path[i + 2], path[i]);
          if (leftish)
            path[i - 1]->L = path[i];
          else
            path[i - 1]->R = path[i];
        }
      else if (path[i + 1]->L == path[i + 2]) {
        bool leftish = (path[i - 1]->L == path[i]);

        path[i]->R = path[i + 2]->L;
        path[i + 1]->L = path[i + 2]->R;
        path[i + 2]->R = path[i + 1];
        path[i + 2]->L = path[i];

        swap(path[i + 2], path[i]);
        if (leftish)
          path[i - 1]->L = path[i];
        else
          path[i - 1]->R = path[i];
      } else {
        bool leftish = (path[i - 1]->L == path[i]);

        path[i]->R = path[i + 1]->L;
        path[i + 1]->L = path[i];
        path[i + 1]->R = path[i + 2]->L;
        path[i + 2]->L = path[i + 1];

        swap(path[i + 2], path[i]);
        if (leftish)
          path[i - 1]->L = path[i];
        else
          path[i - 1]->R = path[i];
      }
    }

    if (i == 2) {
      i -= 2;
      if (path[i]->L == path[i + 1])
        if (path[i + 1]->L == path[i + 2]) {
          path[i]->L = path[i + 1]->R;
          path[i + 1]->R = path[i];
          path[i + 1]->L = path[i + 2]->R;
          path[i + 2]->R = path[i + 1];
        } else {
          path[i]->L = path[i + 2]->R;
          path[i + 1]->R = path[i + 2]->L;
          path[i + 2]->L = path[i + 1];
          path[i + 2]->R = path[i];
        }
      else if (path[i + 1]->L == path[i + 2]) {
        path[i]->R = path[i + 2]->L;
        path[i + 1]->L = path[i + 2]->R;
        path[i + 2]->R = path[i + 1];
        path[i + 2]->L = path[i];
      } else {
        path[i]->R = path[i + 1]->L;
        path[i + 1]->L = path[i];
        path[i + 1]->R = path[i + 2]->L;
        path[i + 2]->L = path[i + 1];
      }
    }

    if (i == 1) {
      i = 0;
      if (path[0]->L == path[1]) {
        path[0]->L = path[1]->R;
        path[1]->R = path[0];
      } else {
        path[0]->R = path[1]->L;
        path[1]->L = path[0];
      }
    }
  }

public:
  bool empty() { return (root == NULL); }
  T extractmin() {
    node *c1 = root, *c2 = root->L;
    if (c2 == NULL) {
      T val = root->key;
      root = root->R;
      return val;
    } else {
      while (c2->L != NULL)
        c2 = c2->L, c1 = c1->L;
      c1->L = c2->R;
      return c2->key;
    }
  }
  splay() { root = NULL; }
  void insert(const T x) {
    Getpath(x);
    Splay();
  }
  bool check(const T x) {
    bool res = getpath(x);
    if (res) {
      Splay();
      return true;
    }
    return false;
  }
  void erase(const T x) {
    if (!getpath(x))
      return;
    if (path[iter - 1]->R != NULL) {
      path[iter] = path[iter - 1]->R;
      ++iter;
      while (path[iter - 1]->L != NULL) {
        path[iter] = path[iter - 1]->L;
        ++iter;
      }
      Splay();
      getpath(x);
      Splay();
      root->R->L = root->L;
      root = root->R;
      return;
    }
    for (int i = iter - 2; i >= 0; --i) {
      if (path[i + 1] != path[i]->R) {
        iter = i + 1;
        Splay();
        getpath(x);
        Splay();
        root->R->L = root->L;
        root = root->R;
        return;
      }
    }
    Splay();
    root = root->L;
  }
};

splay<pair<int, int>> s;
splay<pair<int, int>> checked;
int cnt[10];
namespace fastinput {
/** Interface */

inline int readChar();
template <class T = int> inline T readInt();
template <class T> inline void writeInt(T x, char end = 0);
inline void writeChar(int x);
inline void writeWord(const char *s);

/** Read */

static const int buf_size = 16384;

inline int getChar() {
  static char buf[buf_size];
  static int len = 0, pos = 0;
  if (pos == len)
    pos = 0, len = fread(buf, 1, buf_size, stdin);
  if (pos == len)
    return -1;
  return buf[pos++];
}

inline int readChar() {
  int c = getChar();
  while (c <= 32)
    c = getChar();
  return c;
}

template <class T> inline T readInt() {
  int s = 1, c = readChar();
  T x = 0;
  if (c == '-')
    s = -1, c = getChar();
  while ('0' <= c && c <= '9')
    x = x * 10 + c - '0', c = getChar();
  return s == 1 ? x : -x;
}

/** Write */

static int write_pos = 0;
static char write_buf[buf_size];

inline void writeChar(int x) {
  if (write_pos == buf_size)
    fwrite(write_buf, 1, buf_size, stdout), write_pos = 0;
  write_buf[write_pos++] = x;
}

template <class T> inline void writeInt(T x, char end) {
  if (x < 0)
    writeChar('-'), x = -x;

  char s[24];
  int n = 0;
  while (x || !n)
    s[n++] = '0' + x % 10, x /= 10;
  while (n--)
    writeChar(s[n]);
  if (end)
    writeChar(end);
}

inline void writeWord(const char *s) {
  while (*s)
    writeChar(*s++);
}

struct Flusher {
  ~Flusher() {
    if (write_pos)
      fwrite(write_buf, 1, write_pos, stdout), write_pos = 0;
  }
} flusher;
} // namespace fastinput

using namespace fastinput;

int main() {
  ::ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  int h = readInt(), w = readInt(), n = readInt();
  vector<pair<int, int>> v(n);
  for (int i = 0; i < n; ++i) {
    int x = readInt();
    int y = readInt();
    --x, --y;
    s.insert({x, y});
    v[i] = {x, y};
  }
  for (auto lr : v) {
    int x = lr.first;
    int y = lr.second;
    for (int i = max(0, x - 2); i <= x && i + 2 < h; ++i)
      for (int j = max(0, y - 2); j <= y && j + 2 < w; ++j) {
        if (checked.check({i, j}))
          continue;
        int cntsum = 0;
        for (int x1 = i; x1 <= i + 2; ++x1)
          for (int y1 = j; y1 <= j + 2; ++y1)
            cntsum += s.check({x1, y1});
        checked.insert({i, j});
        ++cnt[cntsum];
      }
  }

  int sum = 0;
  for (int i = 1; i <= 9; ++i)
    sum += cnt[i];

  cout << (h - 2LL) * (w - 2LL) - sum << "\n";
  for (int i = 1; i <= 9; ++i)
    cout << cnt[i] << "\n";

  return 0;
}