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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_Q = 100000;
const int MAX_L = 1000000000;

const long long INF = 1LL << 60;

/* typedef */

typedef long long ll;

struct Treap {
  struct Node {
    ll key, minkey;
    int fix, size;
    Node *left, *right;

    void print(int k) {
      printf("%d: key=%lld, minkey=%lld, fix=%d, size=%d\\n", k, key, minkey,
             fix, size);
    }
    void print() { print(0); }
  };
  typedef Node *node;

  node root, nullnode, buf;
  Node buf0[2 * MAX_Q], buf1;

  Treap() {
    nullnode = &buf1;
    nullnode->left = nullnode->right = nullnode;
    nullnode->key = nullnode->minkey = INF;
    nullnode->fix = nullnode->size = 0;
    clear();
  }

  void clear() {
    buf = buf0;
    root = nullnode;
  }

  int size() { return root->size; }

  void update(node &t) {
    t->size = 1 + t->left->size + t->right->size;
    t->minkey = t->key;
    if (t->minkey > t->left->minkey)
      t->minkey = t->left->minkey;
    if (t->minkey > t->right->minkey)
      t->minkey = t->right->minkey;
  }

  node gen_node(ll x) {
    node t = buf++;
    t->left = t->right = nullnode;
    t->key = t->minkey = x;
    t->fix = rand();
    t->size = 1;
    return t;
  }

  void rot_l(node &k1) {
    node k2 = k1->right;
    k1->right = k2->left;
    k2->left = k1;
    update(k1);
    update(k2);
    k1 = k2;
  }

  void rot_r(node &k1) {
    node k2 = k1->left;
    k1->left = k2->right;
    k2->right = k1;
    update(k1);
    update(k2);
    k1 = k2;
  }

  void append(node &t, ll x) {
    if (t == nullnode)
      t = gen_node(x);
    else {
      append(t->right, x);
      update(t);
      if (t->right->fix > t->fix)
        rot_l(t);
    }
  }
  void append(ll x) { append(root, x); }

  void insert(node &t, ll x) {
    if (t == nullnode)
      t = gen_node(x);
    else if (x < t->key) {
      insert(t->left, x);
      update(t);
      if (t->left->fix > t->fix)
        rot_r(t);
    } else if (x > t->key) {
      insert(t->right, x);
      update(t);
      if (t->right->fix > t->fix)
        rot_l(t);
    }
  }
  void insert(ll x) { insert(root, x); }

  void insertat(node &t, int i, ll x) {
    if (t == nullnode)
      t = gen_node(x);
    else {
      int lsize = t->left->size;
      if (i == lsize) {
        append(t->left, x);
        update(t);
        if (t->left->fix > t->fix)
          rot_r(t);
      } else if (i < lsize) {
        insertat(t->left, i, x);
        update(t);
        if (t->left->fix > t->fix)
          rot_r(t);
      } else {
        insertat(t->right, i - (lsize + 1), x);
        update(t);
        if (t->right->fix > t->fix)
          rot_l(t);
      }
    }
  }
  void insertat(int i, ll x) { insertat(root, i, x); }

  void set(node &t, int i, ll x) {
    if (t != nullnode) {
      int lsize = t->left->size;
      if (i == lsize) {
        t->key = t->minkey = x;
        update(t);
      } else if (i < lsize) {
        set(t->left, i, x);
        update(t);
      } else {
        set(t->right, i - (lsize + 1), x);
        update(t);
      }
    }
  }
  void set(int i, ll x) { set(root, i, x); }

  void remove_node(node &t) {
    if (t == nullnode)
      return;
    if (t->left == nullnode || t->right == nullnode) {
      if (t->left == nullnode)
        t = t->right;
      else
        t = t->left;
    } else {
      if (t->left->fix < t->right->fix) {
        rot_l(t);
        remove_node(t->left);
        update(t);
      } else {
        rot_r(t);
        remove_node(t->right);
        update(t);
      }
    }
  }

  ll removeat(node &t, int i) {
    ll ret = INF;

    if (t != nullnode) {
      int lsize = t->left->size;
      if (i == lsize) {
        ret = t->key;
        remove_node(t);
      } else if (i < lsize) {
        ret = removeat(t->left, i);
        update(t);
      } else {
        ret = removeat(t->right, i - (lsize + 1));
        update(t);
      }
    }

    return ret;
  }
  ll removeat(int i) { return removeat(root, i); }

  int remove_range(node &t, int r0, int r1) {
    if (t == nullnode)
      return 0;
    if (r1 <= 0 || t->size <= r0)
      return 0;

    if (r0 <= 0 && t->size <= r1) {
      int n = t->size;
      t = nullnode;
      return n;
    }

    int lsize = t->left->size;
    int n = remove_range(t->left, r0, r1) +
            remove_range(t->right, r0 - (lsize + 1), r1 - (lsize + 1));
    update(t);

    if (r0 <= lsize && lsize < r1) {
      n++;
      remove_node(t);
    }

    return n;
  }
  int remove_range(int r0, int r1) { return remove_range(root, r0, r1); }

  ll min_range(node &t, int r0, int r1) {
    if (t == nullnode)
      return INF;
    if (r1 <= 0 || t->size <= r0)
      return INF;

    if (r0 <= 0 && t->size <= r1)
      return t->minkey;

    int lsize = t->left->size;
    ll minval = INF;

    if (r0 <= lsize && lsize < r1)
      minval = t->key;
    if (r0 <= lsize) {
      ll minl = min_range(t->left, r0, r1);
      if (minval > minl)
        minval = minl;
    }
    if (lsize + 1 < r1) {
      ll minr = min_range(t->right, r0 - (lsize + 1), r1 - (lsize + 1));
      if (minval > minr)
        minval = minr;
    }

    return minval;
  }
  ll min_range(int r0, int r1) { return min_range(root, r0, r1); }

  node find(ll x) {
    node t = root;
    while (t != nullnode) {
      if (t->key == x)
        return t;
      if (x < t->key)
        t = t->left;
      else
        t = t->right;
    }
    return (node)NULL;
  }

  ll findat(int i) {
    node t = root;
    while (t != nullnode) {
      int lsize = t->left->size;
      if (i == lsize)
        return t->key;
      if (i < lsize)
        t = t->left;
      else {
        i -= lsize + 1;
        t = t->right;
      }
    }
    return INF;
  }

  int upper_bound(ll x) {
    node t = root;
    int k = 0;

    while (t != nullnode) {
      if (t->key <= x) {
        k += t->left->size + 1;
        t = t->right;
      } else {
        t = t->left;
      }
    }
    return k;
  }

  void print(node t, int k, int indent) {
    if (t == nullnode)
      return;
    if (t != NULL) {
      for (int i = 0; i < indent; i++)
        cout << "  ";
      t->print(k + t->left->size);
      print(t->left, k, indent + 1);
      print(t->right, k + t->left->size + 1, indent + 1);
    }
  }
  void print() { print(root, 0, 0); }

  void inorder(node t) {
    if (t != nullnode && t != NULL) {
      inorder(t->left);
      cout << t->key << ' ';
      inorder(t->right);
    }
  }
  void inorder() {
    inorder(root);
    cout << endl;
  }
};

/* global variables */

Treap trp;

/* subroutines */

/* main */

int main() {
  srand(time(NULL));

  for (;;) {
    int qn;
    ll ln;
    cin >> qn >> ln;
    if (qn == 0)
      break;

    trp.clear();
    ll cpos = 0;

    while (qn--) {
      int qi;
      cin >> qi;

      if (qi == 0) {
        trp.insert(cpos + ln);
        // trp.inorder();
      } else if (qi == 1) {
        ll d;
        cin >> d;
        cpos += d;

        int i = trp.upper_bound(cpos);
        int n = trp.remove_range(0, i);
        if (n > 0)
          printf("damage %d\\n", n);
      } else if (qi == 2) {
        int k;
        cin >> k;
        k--;

        ll x = trp.removeat(k);
        cout << ((x < INF) ? "hit" : "miss") << endl;
      } else if (qi == 3) {
        ll x, r;
        cin >> x >> r;

        int i0 = trp.upper_bound(cpos + x - r - 1);
        int i1 = trp.upper_bound(cpos + x + r);
        int n = trp.remove_range(i0, i1);
        printf("bomb %d\\n", n);
      } else {
        int k;
        cin >> k;
        k--;

        ll x = trp.findat(k);
        printf("distance %lld\\n", (x < INF) ? x - cpos : -1);
      }
    }

    cout << "end" << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_Q = 100000;
const int MAX_L = 1000000000;

const long long INF = 1LL << 60;

/* typedef */

typedef long long ll;

struct Treap {
  struct Node {
    ll key, minkey;
    int fix, size;
    Node *left, *right;

    void print(int k) {
      printf("%d: key=%lld, minkey=%lld, fix=%d, size=%d\\n", k, key, minkey,
             fix, size);
    }
    void print() { print(0); }
  };
  typedef Node *node;

  node root, nullnode, buf;
  Node buf0[2 * MAX_Q], buf1;

  Treap() {
    nullnode = &buf1;
    nullnode->left = nullnode->right = nullnode;
    nullnode->key = nullnode->minkey = INF;
    nullnode->fix = nullnode->size = 0;
    clear();
  }

  void clear() {
    buf = buf0;
    root = nullnode;
  }

  int size() { return root->size; }

  void update(node &t) {
    t->size = 1 + t->left->size + t->right->size;
    t->minkey = t->key;
    if (t->minkey > t->left->minkey)
      t->minkey = t->left->minkey;
    if (t->minkey > t->right->minkey)
      t->minkey = t->right->minkey;
  }

  node gen_node(ll x) {
    node t = buf++;
    t->left = t->right = nullnode;
    t->key = t->minkey = x;
    t->fix = rand();
    t->size = 1;
    return t;
  }

  void rot_l(node &k1) {
    node k2 = k1->right;
    k1->right = k2->left;
    k2->left = k1;
    update(k1);
    update(k2);
    k1 = k2;
  }

  void rot_r(node &k1) {
    node k2 = k1->left;
    k1->left = k2->right;
    k2->right = k1;
    update(k1);
    update(k2);
    k1 = k2;
  }

  void append(node &t, ll x) {
    if (t == nullnode)
      t = gen_node(x);
    else {
      append(t->right, x);
      update(t);
      if (t->right->fix > t->fix)
        rot_l(t);
    }
  }
  void append(ll x) { append(root, x); }

  void insert(node &t, ll x) {
    if (t == nullnode)
      t = gen_node(x);
    else if (x < t->key) {
      insert(t->left, x);
      update(t);
    } else if (x > t->key) {
      insert(t->right, x);
      update(t);
    }
  }
  void insert(ll x) { insert(root, x); }

  void insertat(node &t, int i, ll x) {
    if (t == nullnode)
      t = gen_node(x);
    else {
      int lsize = t->left->size;
      if (i == lsize) {
        append(t->left, x);
        update(t);
        if (t->left->fix > t->fix)
          rot_r(t);
      } else if (i < lsize) {
        insertat(t->left, i, x);
        update(t);
        if (t->left->fix > t->fix)
          rot_r(t);
      } else {
        insertat(t->right, i - (lsize + 1), x);
        update(t);
        if (t->right->fix > t->fix)
          rot_l(t);
      }
    }
  }
  void insertat(int i, ll x) { insertat(root, i, x); }

  void set(node &t, int i, ll x) {
    if (t != nullnode) {
      int lsize = t->left->size;
      if (i == lsize) {
        t->key = t->minkey = x;
        update(t);
      } else if (i < lsize) {
        set(t->left, i, x);
        update(t);
      } else {
        set(t->right, i - (lsize + 1), x);
        update(t);
      }
    }
  }
  void set(int i, ll x) { set(root, i, x); }

  void remove_node(node &t) {
    if (t == nullnode)
      return;
    if (t->left == nullnode || t->right == nullnode) {
      if (t->left == nullnode)
        t = t->right;
      else
        t = t->left;
    } else {
      if (t->left->fix < t->right->fix) {
        rot_l(t);
        remove_node(t->left);
        update(t);
      } else {
        rot_r(t);
        remove_node(t->right);
        update(t);
      }
    }
  }

  ll removeat(node &t, int i) {
    ll ret = INF;

    if (t != nullnode) {
      int lsize = t->left->size;
      if (i == lsize) {
        ret = t->key;
        remove_node(t);
      } else if (i < lsize) {
        ret = removeat(t->left, i);
        update(t);
      } else {
        ret = removeat(t->right, i - (lsize + 1));
        update(t);
      }
    }

    return ret;
  }
  ll removeat(int i) { return removeat(root, i); }

  int remove_range(node &t, int r0, int r1) {
    if (t == nullnode)
      return 0;
    if (r1 <= 0 || t->size <= r0)
      return 0;

    if (r0 <= 0 && t->size <= r1) {
      int n = t->size;
      t = nullnode;
      return n;
    }

    int lsize = t->left->size;
    int n = remove_range(t->left, r0, r1) +
            remove_range(t->right, r0 - (lsize + 1), r1 - (lsize + 1));
    update(t);

    if (r0 <= lsize && lsize < r1) {
      n++;
      remove_node(t);
    }

    return n;
  }
  int remove_range(int r0, int r1) { return remove_range(root, r0, r1); }

  ll min_range(node &t, int r0, int r1) {
    if (t == nullnode)
      return INF;
    if (r1 <= 0 || t->size <= r0)
      return INF;

    if (r0 <= 0 && t->size <= r1)
      return t->minkey;

    int lsize = t->left->size;
    ll minval = INF;

    if (r0 <= lsize && lsize < r1)
      minval = t->key;
    if (r0 <= lsize) {
      ll minl = min_range(t->left, r0, r1);
      if (minval > minl)
        minval = minl;
    }
    if (lsize + 1 < r1) {
      ll minr = min_range(t->right, r0 - (lsize + 1), r1 - (lsize + 1));
      if (minval > minr)
        minval = minr;
    }

    return minval;
  }
  ll min_range(int r0, int r1) { return min_range(root, r0, r1); }

  node find(ll x) {
    node t = root;
    while (t != nullnode) {
      if (t->key == x)
        return t;
      if (x < t->key)
        t = t->left;
      else
        t = t->right;
    }
    return (node)NULL;
  }

  ll findat(int i) {
    node t = root;
    while (t != nullnode) {
      int lsize = t->left->size;
      if (i == lsize)
        return t->key;
      if (i < lsize)
        t = t->left;
      else {
        i -= lsize + 1;
        t = t->right;
      }
    }
    return INF;
  }

  int upper_bound(ll x) {
    node t = root;
    int k = 0;

    while (t != nullnode) {
      if (t->key <= x) {
        k += t->left->size + 1;
        t = t->right;
      } else {
        t = t->left;
      }
    }
    return k;
  }

  void print(node t, int k, int indent) {
    if (t == nullnode)
      return;
    if (t != NULL) {
      for (int i = 0; i < indent; i++)
        cout << "  ";
      t->print(k + t->left->size);
      print(t->left, k, indent + 1);
      print(t->right, k + t->left->size + 1, indent + 1);
    }
  }
  void print() { print(root, 0, 0); }

  void inorder(node t) {
    if (t != nullnode && t != NULL) {
      inorder(t->left);
      cout << t->key << ' ';
      inorder(t->right);
    }
  }
  void inorder() {
    inorder(root);
    cout << endl;
  }
};

/* global variables */

Treap trp;

/* subroutines */

/* main */

int main() {
  srand(time(NULL));

  for (;;) {
    int qn;
    ll ln;
    cin >> qn >> ln;
    if (qn == 0)
      break;

    trp.clear();
    ll cpos = 0;

    while (qn--) {
      int qi;
      cin >> qi;

      if (qi == 0) {
        trp.insert(cpos + ln);
        // trp.inorder();
      } else if (qi == 1) {
        ll d;
        cin >> d;
        cpos += d;

        int i = trp.upper_bound(cpos);
        int n = trp.remove_range(0, i);
        if (n > 0)
          printf("damage %d\\n", n);
      } else if (qi == 2) {
        int k;
        cin >> k;
        k--;

        ll x = trp.removeat(k);
        cout << ((x < INF) ? "hit" : "miss") << endl;
      } else if (qi == 3) {
        ll x, r;
        cin >> x >> r;

        int i0 = trp.upper_bound(cpos + x - r - 1);
        int i1 = trp.upper_bound(cpos + x + r);
        int n = trp.remove_range(i0, i1);
        printf("bomb %d\\n", n);
      } else {
        int k;
        cin >> k;
        k--;

        ll x = trp.findat(k);
        printf("distance %lld\\n", (x < INF) ? x - cpos : -1);
      }
    }

    cout << "end" << endl;
  }

  return 0;
}