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

//

// g++ -std=c++11 abc145_c.cc && ./a.out
#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using namespace std;
using ll = long long;
using P = pair<int, int>;

bool isContained(int needle, vector<int> &haystack, int min, int max) {
  int mid = (max + min) / 2;
  if (max - min <= 2) {
    return (needle == haystack[min]) || (needle == haystack[max]) ||
           (needle == haystack[mid]);
  }

  if (needle < haystack[mid]) {
    return isContained(needle, haystack, min, mid);
  } else if (needle > haystack[mid]) {
    return isContained(needle, haystack, mid, max);
  } else {
    return true;
  }
}

int main() {
  int n, q, i, j;
  cin >> n;

  // 重複あり
  vector<int> S(n);
  rep(i, n) cin >> S[i];
  sort(S.begin(), S.end());

  cin >> q;
  // すべて異なる
  vector<int> T(q);
  rep(i, q) cin >> T[i];

  int count = 0;
  rep(i, q) {
    int t = T[i];
    if (isContained(t, S, 0, S.size() - 1)) {
      // for debug
      // cout << t << " is contained" << endl;

      count++;
    }
  }
  cout << count << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <string>
#include <typeinfo>
#include <vector>
#define _USE_MATH_DEFINES
#include <cmath>
#include <queue>
#include <stack>

using namespace std;

int main() {

  int n, q;
  cin >> n;
  vector<int> seq1(n);
  for (int i = 0; i < n; i++) {
    cin >> seq1[i];
  }
  cin >> q;
  vector<int> seq2(q);
  for (int i = 0; i < q; i++) {
    cin >> seq2[i];
  }

  // seq1内のかぶり数の削除
  // seq1はinputの段階で既にsort済
  vector<int>::iterator itr = seq1.begin();
  while (itr != seq1.end()) {
    if (*itr == *(itr + 1)) {
      seq1.erase(itr);
      itr--;
    }
    itr++;
  }
  // seq1内整数の最大値、最小値の取得(Binary Searchに使用)
  vector<int>::iterator itr1_min = seq1.begin();
  vector<int>::iterator itr1_max = seq1.end();
  itr1_max--;
  int min_in_seq1 = *itr1_min;
  int max_in_seq1 = *itr1_max;

  sort(seq2.begin(), seq2.end());
  vector<int>::iterator itr2 = seq2.begin();
  while (itr2 != seq2.end()) {
    if (*itr2 == *(itr2 + 1)) {
      seq2.erase(itr2);
      itr2--;
    }
    itr2++;
  }

  int both_num = 0;

  int size1 = seq1.size() - 1;
  int size2 = seq2.size();

  // すべてseq1のindex
  int index = size1;
  int index_max = size1;
  index /= 2;
  int index_mid = index;

  for (int i = 0; i < size2; i++) {
    int seq2_val = seq2[i];
    if (!(min_in_seq1 <= seq2_val && seq2_val <= max_in_seq1)) {
      continue;
    }
    // min <= size2[i] <= maxのときのループ処理
    // seq2_valは固定

    index = index_mid;

    while (true) {
      if (seq2_val < seq1[index]) {
        index /= 2;
        continue;
      } else if (seq1[index] < seq2_val) {

        index = index + (index_max - index) / 2;

        // どちらのindexもだめ
        // max_indexとmin_indexを取得して比較したほうが良い

        // 2->4->2->4->...
        // index = index + (index/2) + 1;

        // 3->1->1->1...
        // index = index + (index/2);
        continue;
      } else {
        both_num += 1;
        break;
      }
    }
  }

  cout << both_num << endl;

  return 0;
}