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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info {
  bool operator<(const struct Info &arg) const { return score < arg.score; };
  int score, id;
};

int main() {

  int N, Q;
  scanf("%d %d", &N, &Q);

  Info *info = (Info *)malloc(sizeof(Info) * (N + 1));

  info[0].score = -1;
  vector<int> SCORE;
  SCORE.push_back(-1);
  for (int i = 1; i <= N; i++) {
    scanf("%d", &info[i].score);
    SCORE.push_back(info[i].score);
  }

  sort(SCORE.begin(), SCORE.end());

  int *score_ruisekiwa = new int[N + 1];
  int *score = new int[N + 1];

  int score_index = 1;

  score[0] = -1;
  score_ruisekiwa[0] = 0;

  for (int i = 1; i <= N;) {

    score[score_index] = SCORE[i];
    score_ruisekiwa[score_index] = 0;

    while (score[score_index] == SCORE[i] && i <= N) {
      score_ruisekiwa[score_index]++;
      i++;
    }
    score_ruisekiwa[score_index] += score_ruisekiwa[score_index - 1];
    score_index++;
  }

  int *loc = new int[N + 1];

  int left, right, m;

  for (int i = 1; i <= N; i++) {

    left = 1, right = score_index - 1, m = (left + right) / 2;

    while (left <= right) {
      if (score[m] == info[i].score) {
        loc[i] = m;
        break;
      } else if (score[m] < info[i].score) {
        left = m + 1;
      } else {
        right = m - 1;
      }
      m = (left + right) / 2;
    }
  }

  char order[10];
  int value, current_number, need_number, max_loc;

  bool *check = new bool[score_index];

  vector<int> V;
  vector<Info> work;
  bool FLG;

  int calc_left, calc_right, calc_m;

  for (int loop = 0; loop < Q; loop++) {
    scanf("%s %d", order, &value);

    switch (order[0]) {
    case 'A':
      V.push_back(value);
      break;
    case 'R':
      for (int i = 0; i < V.size(); i++) {
        if (V[i] == value) {
          V.erase(V.begin() + i);
          break;
        }
      }
      break;
    case 'C':

      work.clear();

      need_number = N - value;
      max_loc = 0;

      for (int i = 0; i <= score_index - 1; i++)
        check[i] = false;

      for (int i = 0; i < V.size(); i++) {
        max_loc = max(max_loc, loc[V[i]]);
        FLG = true;
        for (int k = i + 1; k < V.size(); k++) {
          if (loc[V[i]] == loc[V[k]]) {
            FLG = false;
          }
        }
        if (FLG) {
          Info new_info;
          new_info.id = V[i];
          new_info.score = score[loc[V[i]]];
          work.push_back(new_info);
          check[loc[V[i]]] = true;
        }
      }

      if (score_ruisekiwa[max_loc] < need_number) {
        printf("NA\\n");
        continue;
      }

      current_number = 0;
      for (int i = 0; i < work.size(); i++) {
        current_number += score_ruisekiwa[loc[work[i].id]] -
                          score_ruisekiwa[loc[work[i].id] - 1];
      }

      if (current_number >= need_number) {
        printf("0\\n");
        continue;
      }

      int ans = 0;
      int left_loc, right_loc;

      sort(work.begin(), work.end());

      left = 0, right = score[max_loc], m = (left + right) / 2;

      while (left <= right) {

        int tmp = 0;

        for (int i = 0; i < work.size(); i++) {

          int left_score = 0;
          if (i > 0) {
            left_score = work[i - 1].score;

            if (work[i].score - m <= left_score) {

              left_loc = loc[work[i - 1].id] + 1;
              right_loc = loc[work[i].id] - 1;

              if (left_loc <= right_loc) {
                tmp +=
                    score_ruisekiwa[right_loc] - score_ruisekiwa[left_loc - 1];
              }
            } else {

              if (work[i].score - m > score[loc[work[i].id] - 1]) {
                continue;
              }
              right_loc = loc[work[i].id] - 1;

              calc_left = loc[work[i - 1].id] + 1;
              calc_right = right_loc;
              calc_m = (calc_left + calc_right) / 2;

              while (calc_left <= calc_right) {

                if (score[calc_m] >= work[i].score - m) {
                  left_loc = calc_m;
                  calc_right = calc_m - 1;
                } else {
                  calc_left = calc_m + 1;
                }
                calc_m = (calc_left + calc_right) / 2;
              }
              tmp += score_ruisekiwa[right_loc] - score_ruisekiwa[left_loc - 1];
            }

          } else { // i == 0

            if (loc[work[i].id] == 1 ||
                work[i].score - m > score[loc[work[i].id] - 1]) {
              continue;
            }

            right_loc = loc[work[i].id] - 1;

            calc_left = 1;
            calc_right = right_loc;
            calc_m = (calc_left + calc_right) / 2;

            while (calc_left <= calc_right) {

              if (score[calc_m] >= work[i].score - m) {
                left_loc = calc_m;
                calc_right = calc_m - 1;
              } else {
                calc_left = calc_m + 1;
              }
              calc_m = (calc_left + calc_right) / 2;
            }
            tmp += score_ruisekiwa[right_loc] - score_ruisekiwa[left_loc - 1];
          }
        }

        if (current_number + tmp >= need_number) {
          ans = m;
          right = m - 1;
        } else {
          left = m + 1;
        }
        m = (left + right) / 2;
      }

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

      break;
    }
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info {
  bool operator<(const struct Info &arg) const { return score < arg.score; };
  int score;
};

struct Data {
  Data(int arg_diff, int arg_index, int arg_leader_number) {
    diff = arg_diff;
    index = arg_index;
    leader_number = arg_leader_number;
  }
  bool operator<(const struct Data &arg) const { return diff > arg.diff; };
  int diff, index, leader_number;
};

int main() {

  int N, Q;
  scanf("%d %d", &N, &Q);

  Info *info = (Info *)malloc(sizeof(Info) * (N + 1));

  info[0].score = -1;
  vector<int> SCORE;
  SCORE.push_back(-1);
  for (int i = 1; i <= N; i++) {
    scanf("%d", &info[i].score);
    SCORE.push_back(info[i].score);
  }

  sort(SCORE.begin(), SCORE.end());

  int *score_ruisekiwa = new int[N + 1];
  int *score = new int[N + 1];

  int score_index = 1;

  score[0] = -1;
  score_ruisekiwa[0] = 0;

  for (int i = 1; i <= N;) {

    score[score_index] = SCORE[i];
    score_ruisekiwa[score_index] = 0;

    while (score[score_index] == SCORE[i] && i <= N) {
      score_ruisekiwa[score_index]++;
      i++;
    }
    score_ruisekiwa[score_index] += score_ruisekiwa[score_index - 1];
    score_index++;
  }

  int *loc = new int[N + 1];

  int left, right, m;

  for (int i = 1; i <= N; i++) {

    left = 1, right = score_index - 1, m = (left + right) / 2;

    while (left <= right) {
      if (score[m] == info[i].score) {
        loc[i] = m;
        break;
      } else if (score[m] < info[i].score) {
        left = m + 1;
      } else {
        right = m - 1;
      }
      m = (left + right) / 2;
    }
  }

  char order[10];
  int value, current_number, need_number, max_loc;

  bool *check = new bool[score_index];

  vector<int> V, work;
  priority_queue<Data> PQ;
  bool FLG;

  for (int loop = 0; loop < Q; loop++) {
    scanf("%s %d", order, &value);

    switch (order[0]) {
    case 'A':
      V.push_back(value);
      break;
    case 'R':
      for (int i = 0; i < V.size(); i++) {
        if (V[i] == value) {
          V.erase(V.begin() + i);
          break;
        }
      }
      break;
    case 'C':

      work.clear();

      need_number = N - value;
      max_loc = 0;

      for (int i = 0; i <= score_index - 1; i++)
        check[i] = false;

      for (int i = 0; i < V.size(); i++) {
        max_loc = max(max_loc, loc[V[i]]);
        FLG = true;
        for (int k = i + 1; k < V.size(); k++) {
          if (loc[V[i]] == loc[V[k]]) {
            FLG = false;
          }
        }
        if (FLG) {
          work.push_back(V[i]);
          check[loc[V[i]]] = true;
        }
      }

      if (score_ruisekiwa[max_loc] < need_number) {
        printf("NA\\n");
        continue;
      }

      current_number = 0;
      for (int i = 0; i < work.size(); i++) {
        current_number +=
            score_ruisekiwa[loc[work[i]]] - score_ruisekiwa[loc[work[i]] - 1];
      }

      if (current_number >= need_number) {
        printf("0\\n");
        continue;
      }

      while (!PQ.empty())
        PQ.pop();

      for (int i = 0; i < work.size(); i++) {
        if (loc[work[i]] >= 2 && check[loc[work[i]] - 1] == false) {
          PQ.push(Data(info[work[i]].score - score[loc[work[i]] - 1],
                       loc[work[i]] - 1, i));
        }
      }

      int ans = 0;

      while (current_number < need_number) {
        ans = max(ans, PQ.top().diff);

        check[PQ.top().index] = true;

        current_number += score_ruisekiwa[PQ.top().index] -
                          score_ruisekiwa[PQ.top().index - 1];

        if (PQ.top().index > 1 && check[PQ.top().index - 1] == false) {
          PQ.push(Data(info[work[PQ.top().leader_number]].score -
                           score[PQ.top().index - 1],
                       PQ.top().index - 1, PQ.top().leader_number));
        }
        PQ.pop();
      }

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

      break;
    }
  }

  return 0;
}