Problem p00598 (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 <time.h>
#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;

vector<int> U;
vector<int> V[5];
int loc[128], N, length;
char buf[2], equation[2000];

vector<int> calc_union(vector<int> A, vector<int> B) {

  vector<int> ret;

  for (int i = 0; i < A.size(); i++) {
    ret.push_back(A[i]);
  }

  for (int i = 0; i < B.size(); i++) {
    ret.push_back(B[i]);
  }

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

  ret.erase(unique(ret.begin(), ret.end()), ret.end());

  return ret;
}

vector<int> calc_intersection(vector<int> A, vector<int> B) {

  vector<int> ret;

  map<int, bool> MAP;

  for (int i = 0; i < A.size(); i++) {
    MAP[A[i]] = true;
  }

  for (int i = 0; i < B.size(); i++) {
    auto at = MAP.find(B[i]);
    if (at != MAP.end()) {
      ret.push_back(B[i]);
    }
  }
  return ret;
}

vector<int> calc_diff(vector<int> A, vector<int> B) {

  vector<int> ret;

  map<int, bool> MAP;

  for (int i = 0; i < B.size(); i++) {
    MAP[B[i]] = true;
  }

  for (int i = 0; i < A.size(); i++) {
    auto at = MAP.find(A[i]);
    if (at == MAP.end()) {
      ret.push_back(A[i]);
    }
  }
  return ret;
}

vector<int> calc_sym_diff(vector<int> A, vector<int> B) {

  vector<int> ret;

  map<int, bool> MAP;

  for (int i = 0; i < B.size(); i++) {
    MAP[B[i]] = true;
  }

  for (int i = 0; i < A.size(); i++) {
    auto at = MAP.find(A[i]);
    if (at == MAP.end()) {
      ret.push_back(A[i]);
    }
  }

  MAP.clear();

  for (int i = 0; i < A.size(); i++) {
    MAP[A[i]] = true;
  }

  for (int i = 0; i < B.size(); i++) {
    auto at = MAP.find(B[i]);
    if (at == MAP.end()) {
      ret.push_back(B[i]);
    }
  }

  return ret;
}

vector<int> calc_complement(vector<int> A) {

  vector<int> ret;

  map<int, bool> MAP;

  for (int i = 0; i < A.size(); i++) {
    MAP[A[i]] = true;
  }

  for (int i = 0; i < U.size(); i++) {
    auto at = MAP.find(U[i]);
    if (at == MAP.end()) {
      ret.push_back(U[i]);
    }
  }

  return ret;
}

void makeU() {

  U.clear();

  for (int i = 0; i < N; i++) {
    for (int k = 0; k < V[i].size(); k++) {
      U.push_back(V[i][k]);
    }
  }
  sort(U.begin(), U.end());
  U.erase(unique(U.begin(), U.end()), U.end());
}

vector<int> recursive(int left, int right) {

  /*printf("\\n\\nleft:%d right:%d\\n",left,right);
  for(int i = left; i <= right; i++){
          printf("%c",equation[i]);
  }
  printf("\\n");*/

  vector<int> calc_left, calc_right;

  int index = left, depth, close_pos;
  char pre = '@';

  while (index <= right) {

    switch (equation[index]) {
    case '(':
      // printf("???????????????\\n");
      depth = 0;
      for (int i = index; i <= right; i++) {
        if (equation[i] == '(')
          depth++;
        else if (equation[i] == ')') {
          depth--;
          if (depth == 0) {
            close_pos = i;
            break;
          }
        }
      }
      if (pre == '@') {
        // printf("left??±??????()\\n");
        calc_left = recursive(index + 1, close_pos - 1);
        /*for(int k = 0; k < calc_left.size(); k++){
                printf("calc_left[%d]:%d\\n",k,calc_left[k]);
        }*/
      } else {

        // printf("right??±??????()\\n");
        calc_right = recursive(index + 1, close_pos - 1);
        /*for(int k = 0; k < calc_right.size(); k++){
                printf("calc_right[%d]:%d\\n",k,calc_right[k]);
        }*/

        switch (pre) {
        case 'u':
          calc_left = calc_union(calc_left, calc_right);
          break;
        case 'i':
          calc_left = calc_intersection(calc_left, calc_right);
          break;
        case 'd':
          calc_left = calc_diff(calc_left, calc_right);
          break;
        case 's':
          calc_left = calc_sym_diff(calc_left, calc_right);
          break;
        case 'c':
          calc_left = calc_complement(calc_right);
          break;
        }
      }
      /*for(int k = 0; k < calc_left.size(); k++){
              printf("calc_left[%d]:%d\\n",k,calc_left[k]);
      }*/
      pre = ')';
      index = close_pos + 1;
      break;
    case 'u':
    case 'i':
    case 'd':
    case 's':
    case 'c':
      // printf("?????????:%c\\n",equation[index]);
      pre = equation[index];
      index++;
      break;
    default: // A-E
      /*printf("??????:%c\\n",equation[index]);
      for(int k = 0; k < calc_left.size(); k++){
              printf("??? calc_left[%d]:%d\\n",k,calc_left[k]);
      }*/
      switch (pre) {
      case '@':
        calc_left = V[loc[equation[index] - 'A']];
        break;
      case 'u':
        calc_left = calc_union(calc_left, V[loc[equation[index] - 'A']]);
        break;
      case 'i':
        // printf("%d??¨intersect\\n",loc[equation[index]-'A']);
        calc_left = calc_intersection(calc_left, V[loc[equation[index] - 'A']]);
        break;
      case 'd':
        calc_left = calc_diff(calc_left, V[loc[equation[index] - 'A']]);
        break;
      case 's':
        calc_left = calc_sym_diff(calc_left, V[loc[equation[index] - 'A']]);
        break;
      case 'c':
        calc_left = calc_complement(V[loc[equation[index] - 'A']]);
        break;
      }
      /*for(int k = 0; k < calc_left.size(); k++){
              printf("calc_left[%d]:%d\\n",k,calc_left[k]);
      }*/
      pre = 'X';
      index++;
      break;
    }
  }

  return calc_left;
}

void func() {

  for (int i = 0; i < 5; i++)
    V[i].clear();

  int index = 0;

  int num, tmp;
  scanf("%d", &num);

  loc[buf[0] - 'A'] = index;

  for (int i = 0; i < num; i++) {
    scanf("%d", &tmp);
    V[index].push_back(tmp);
  }
  index++;

  while (true) {
    scanf("%s %d", buf, &num);
    if (buf[0] == 'R' && num == 0)
      break;

    loc[buf[0] - 'A'] = index;
    for (int i = 0; i < num; i++) {
      scanf("%d", &tmp);
      V[index].push_back(tmp);
    }
    index++;
  }

  N = index;

  makeU();

  scanf("%s", equation);

  /*for(int i = 0; i < U.size(); i++){
          printf("U[%d]:%d\\n",i,U[i]);
  }*/

  for (length = 0; equation[length] != '\\0'; length++)
    ;

  vector<int> ans = recursive(0, length - 1);

  if (ans.size() == 0) {
    printf("NULL\\n");
  } else {
    printf("%d", ans[0]);
    for (int i = 1; i < ans.size(); i++) {
      printf(" %d", ans[i]);
    }
    printf("\\n");
  }
}

int main() {

  while (scanf("%s", buf) != EOF) {
    func();
  }

  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 <time.h>
#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;

vector<int> U;
vector<int> V[5];
int loc[128], N, length;
char buf[2], equation[1000];

vector<int> calc_union(vector<int> A, vector<int> B) {

  vector<int> ret;

  bool check[101];

  for (int i = 1; i <= 100; i++)
    check[i] = false;

  for (int i = 0; i < A.size(); i++) {
    check[A[i]] = true;
  }

  for (int i = 0; i < B.size(); i++) {
    check[B[i]] = true;
  }

  for (int i = 1; i <= 100; i++) {
    if (check[i])
      ret.push_back(i);
  }
  return ret;
}

vector<int> calc_intersection(vector<int> A, vector<int> B) {

  vector<int> ret;

  int check[101];

  for (int i = 1; i <= 100; i++)
    check[i] = 0;

  for (int i = 0; i < A.size(); i++) {
    check[A[i]]++;
  }

  for (int i = 0; i < B.size(); i++) {
    check[B[i]]++;
  }

  for (int i = 1; i <= 100; i++) {
    if (check[i] == 2)
      ret.push_back(i);
  }
  return ret;
}

vector<int> calc_diff(vector<int> A, vector<int> B) {

  vector<int> ret;

  bool check[101];

  for (int i = 1; i <= 100; i++)
    check[i] = false;

  for (int i = 0; i < B.size(); i++) {
    check[B[i]] = true;
  }

  for (int i = 0; i < A.size(); i++) {
    if (check[A[i]] == false) {
      ret.push_back(A[i]);
    }
  }
  return ret;
}

vector<int> calc_sym_diff(vector<int> A, vector<int> B) {

  vector<int> ret;

  int check[101];

  for (int i = 1; i <= 100; i++)
    check[i] = 0;

  for (int i = 0; i < A.size(); i++) {
    check[A[i]]++;
  }

  for (int i = 0; i < B.size(); i++) {
    check[B[i]]++;
  }

  for (int i = 1; i <= 100; i++) {
    if (check[i] == 1)
      ret.push_back(i);
  }
  return ret;
}

vector<int> calc_complement(vector<int> A) {

  vector<int> ret;

  bool check[101];
  for (int i = 1; i <= 100; i++)
    check[i] = false;

  for (int i = 0; i < A.size(); i++) {
    check[A[i]] = true;
  }

  for (int i = 0; i < U.size(); i++) {
    if (check[U[i]] == false) {
      ret.push_back(U[i]);
    }
  }

  return ret;
}

void makeU() {

  U.clear();

  bool check[101];
  for (int i = 1; i <= 100; i++)
    check[i] = false;

  for (int i = 0; i < N; i++) {
    for (int k = 0; k < V[i].size(); k++) {
      check[V[i][k]] = true;
    }
  }

  for (int i = 1; i <= 100; i++) {
    if (check[i])
      U.push_back(i);
  }
}

vector<int> recursive(int left, int right) {

  /*printf("\\n\\nleft:%d right:%d\\n",left,right);
  for(int i = left; i <= right; i++){
          printf("%c",equation[i]);
  }
  printf("\\n");*/

  vector<int> calc_left, calc_right;

  int index = left, depth, close_pos;
  char pre = '@';

  while (index <= right) {

    switch (equation[index]) {
    case '(':
      // printf("???????????????\\n");
      depth = 0;
      for (int i = index; i <= right; i++) {
        if (equation[i] == '(')
          depth++;
        else if (equation[i] == ')') {
          depth--;
          if (depth == 0) {
            close_pos = i;
            break;
          }
        }
      }
      if (pre == '@') {
        // printf("left??±??????()\\n");
        calc_left = recursive(index + 1, close_pos - 1);
        /*for(int k = 0; k < calc_left.size(); k++){
                printf("calc_left[%d]:%d\\n",k,calc_left[k]);
        }*/
      } else {

        // printf("right??±??????()\\n");
        calc_right = recursive(index + 1, close_pos - 1);
        /*for(int k = 0; k < calc_right.size(); k++){
                printf("calc_right[%d]:%d\\n",k,calc_right[k]);
        }*/

        switch (pre) {
        case 'u':
          calc_left = calc_union(calc_left, calc_right);
          break;
        case 'i':
          calc_left = calc_intersection(calc_left, calc_right);
          break;
        case 'd':
          calc_left = calc_diff(calc_left, calc_right);
          break;
        case 's':
          calc_left = calc_sym_diff(calc_left, calc_right);
          break;
        case 'c':
          calc_left = calc_complement(calc_right);
          break;
        }
      }
      /*for(int k = 0; k < calc_left.size(); k++){
              printf("calc_left[%d]:%d\\n",k,calc_left[k]);
      }*/
      pre = ')';
      index = close_pos + 1;
      break;
    case 'u':
    case 'i':
    case 'd':
    case 's':
    case 'c':
      // printf("?????????:%c\\n",equation[index]);
      pre = equation[index];
      index++;
      break;
    default: // A-E
      /*printf("??????:%c\\n",equation[index]);
      for(int k = 0; k < calc_left.size(); k++){
              printf("??? calc_left[%d]:%d\\n",k,calc_left[k]);
      }*/
      switch (pre) {
      case '@':
        calc_left = V[loc[equation[index] - 'A']];
        break;
      case 'u':
        calc_left = calc_union(calc_left, V[loc[equation[index] - 'A']]);
        break;
      case 'i':
        // printf("%d??¨intersect\\n",loc[equation[index]-'A']);
        calc_left = calc_intersection(calc_left, V[loc[equation[index] - 'A']]);
        break;
      case 'd':
        calc_left = calc_diff(calc_left, V[loc[equation[index] - 'A']]);
        break;
      case 's':
        calc_left = calc_sym_diff(calc_left, V[loc[equation[index] - 'A']]);
        break;
      case 'c':
        calc_left = calc_complement(V[loc[equation[index] - 'A']]);
        break;
      }
      /*for(int k = 0; k < calc_left.size(); k++){
              printf("calc_left[%d]:%d\\n",k,calc_left[k]);
      }*/
      pre = 'X';
      index++;
      break;
    }
  }

  return calc_left;
}

void func() {

  for (int i = 0; i < 5; i++)
    V[i].clear();

  int index = 0;

  int num, tmp;
  scanf("%d", &num);

  loc[buf[0] - 'A'] = index;

  for (int i = 0; i < num; i++) {
    scanf("%d", &tmp);
    V[index].push_back(tmp);
  }
  index++;

  while (true) {
    scanf("%s %d", buf, &num);
    if (buf[0] == 'R' && num == 0)
      break;

    loc[buf[0] - 'A'] = index;
    for (int i = 0; i < num; i++) {
      scanf("%d", &tmp);
      V[index].push_back(tmp);
    }
    index++;
  }

  N = index;

  makeU();

  scanf("%s", equation);

  /*for(int i = 0; i < U.size(); i++){
          printf("U[%d]:%d\\n",i,U[i]);
  }*/

  for (length = 0; equation[length] != '\\0'; length++)
    ;

  vector<int> ans = recursive(0, length - 1);

  if (ans.size() == 0) {
    printf("NULL\\n");
  } else {
    printf("%d", ans[0]);
    for (int i = 1; i < ans.size(); i++) {
      printf(" %d", ans[i]);
    }
    printf("\\n");
  }
}

int main() {

  while (~scanf("%s", buf)) {
    func();
  }

  return 0;
}