Problem p03081 (C++)

Buggy submission (status: Time Limit Exceeded):
/*
memo for solution
*/
#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <sys/time.h>
#include <utility>
#include <vector>
using namespace std;
double e_time(void) {
  static struct timeval now;
  gettimeofday(&now, NULL);
  return (double)(now.tv_sec + now.tv_usec / 1000000.0);
}
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define pb push_back
#define mp make_pair
#define ALL(C) (C).begin(), (C).end()
#define fe(c, itr)                                                             \
  for (__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); itr++)
#define BITSHIFT(X) ((1 << (X)))
#define CONTAIN(S, X) (((S)&BITSHIFT(X)) != 0)
typedef complex<double> P;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vint;
template <class T> void vp(T &a, int p) {
  rep(i, p) cout << a[i] << " ";
  cout << endl;
}
template <class T> T ceilUp(const T &a, const T &b) { return (a + b - 1) / b; }
const ll mod = 1000000009;
inline ll modadd(ll a, ll b) {
  a %= mod;
  b %= mod;
  return (a + b) % mod;
}
inline ll modsub(ll a, ll b) {
  a %= mod;
  b %= mod;
  a -= b;
  a %= mod;
  if (a < 0)
    a += mod;
  return a;
}
inline ll modmul(ll a, ll b) {
  a %= mod;
  b %= mod;
  return (a * b) % mod;
}
inline ll modeq(ll a, ll b, ll m) {
  a = (a % m + m) % m;
  b = (b % m + m) % m;
  return a == b;
}
// ll modpow(ll n,ll p){if (p == 0)return 1;if (p == 1)return n;ll
// ret=mypow(n,p/2);ret=ret*ret%mod;if (p&1)ret=ret*n%mod;return ret;} ll
// getinv(ll a){return mypow(a,mod-2);}
ll mypow(ll n, ll p) {
  if (p == 0)
    return 1;
  if (p == 1)
    return n;
  ll ret = mypow(n, p / 2);
  ret = ret * ret;
  if (p & 1)
    ret = ret * n;
  return ret;
}

bool check(int n, const string &in, vector<char> &pos, vector<int> &order,
           bool isCountLeft, int my_pos) {
  const int q = pos.size();
  rep(i, q) {
    if (in[my_pos] == pos[i]) {
      my_pos += order[i];
    }
    if (my_pos < 0 || my_pos >= n)
      break;
  }

  if (isCountLeft && my_pos < 0)
    return true;
  if (!isCountLeft && my_pos >= n)
    return true;
  return false;
}

int solve(int n, const string &in, vector<char> &pos, vector<int> &order,
          bool isCountLeft) {
  int l = 0, r = n;
  if (isCountLeft && !check(n, in, pos, order, isCountLeft, 0)) {
    return 0;
  } else if (!isCountLeft && !check(n, in, pos, order, isCountLeft, n - 1)) {
    return 0;
  }
  if (!isCountLeft) {
    l = -1;
    r = n - 1;
  }
  while (l + 1 <= r) {
    // rep(i,50){
    int mid = (l + r) / 2;
    bool isGone = check(n, in, pos, order, isCountLeft, mid);
    // cout << isCountLeft <<" " << l  <<" " << r << " " << mid << " " << isGone
    // << endl;
    if (isGone) {
      if (isCountLeft) {
        l = mid; // find max
      } else {
        r = mid; // find min
      }
    } else {
      if (isCountLeft) {
        r = mid; // find max
      } else {
        l = mid; // find min
      }
    }
  }
  // cout << isCountLeft <<" l = " << l <<" r = " << r <<" " << l << " " << n-r
  // << endl;
  if (isCountLeft) {
    return l + 1;
  } else {
    return n - r;
  }
}

int main() {
  int n, q;
  cin >> n >> q;
  string in;
  cin >> in;
  vector<char> pos(q);
  vector<int> order(q);
  rep(i, q) {
    cin >> pos[i];
    char tmp;
    cin >> tmp;
    if (tmp == 'L')
      order[i] = -1;
    else if (tmp == 'R')
      order[i] = +1;
    else
      assert(0);
  }
  int goneLeft = solve(n, in, pos, order, true);
  int goneRight = solve(n, in, pos, order, false);
  cout << n - goneLeft - goneRight << endl;

  return 0;
}


Fixed submission:
/*
memo for solution
*/
#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <sys/time.h>
#include <utility>
#include <vector>
using namespace std;
double e_time(void) {
  static struct timeval now;
  gettimeofday(&now, NULL);
  return (double)(now.tv_sec + now.tv_usec / 1000000.0);
}
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define pb push_back
#define mp make_pair
#define ALL(C) (C).begin(), (C).end()
#define fe(c, itr)                                                             \
  for (__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); itr++)
#define BITSHIFT(X) ((1 << (X)))
#define CONTAIN(S, X) (((S)&BITSHIFT(X)) != 0)
typedef complex<double> P;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vint;
template <class T> void vp(T &a, int p) {
  rep(i, p) cout << a[i] << " ";
  cout << endl;
}
template <class T> T ceilUp(const T &a, const T &b) { return (a + b - 1) / b; }
const ll mod = 1000000009;
inline ll modadd(ll a, ll b) {
  a %= mod;
  b %= mod;
  return (a + b) % mod;
}
inline ll modsub(ll a, ll b) {
  a %= mod;
  b %= mod;
  a -= b;
  a %= mod;
  if (a < 0)
    a += mod;
  return a;
}
inline ll modmul(ll a, ll b) {
  a %= mod;
  b %= mod;
  return (a * b) % mod;
}
inline ll modeq(ll a, ll b, ll m) {
  a = (a % m + m) % m;
  b = (b % m + m) % m;
  return a == b;
}
// ll modpow(ll n,ll p){if (p == 0)return 1;if (p == 1)return n;ll
// ret=mypow(n,p/2);ret=ret*ret%mod;if (p&1)ret=ret*n%mod;return ret;} ll
// getinv(ll a){return mypow(a,mod-2);}
ll mypow(ll n, ll p) {
  if (p == 0)
    return 1;
  if (p == 1)
    return n;
  ll ret = mypow(n, p / 2);
  ret = ret * ret;
  if (p & 1)
    ret = ret * n;
  return ret;
}

bool check(int n, const string &in, vector<char> &pos, vector<int> &order,
           bool isCountLeft, int my_pos) {
  const int q = pos.size();
  rep(i, q) {
    if (in[my_pos] == pos[i]) {
      my_pos += order[i];
    }
    if (my_pos < 0 || my_pos >= n)
      break;
  }

  if (isCountLeft && my_pos < 0)
    return true;
  if (!isCountLeft && my_pos >= n)
    return true;
  return false;
}

int solve(int n, const string &in, vector<char> &pos, vector<int> &order,
          bool isCountLeft) {
  int l = 0, r = n;
  if (isCountLeft && !check(n, in, pos, order, isCountLeft, 0)) {
    return 0;
  } else if (!isCountLeft && !check(n, in, pos, order, isCountLeft, n - 1)) {
    return 0;
  }
  if (!isCountLeft) {
    l = -1;
    r = n - 1;
  }
  // while(l < r){
  rep(i, 50) {
    int mid = (l + r) / 2;
    bool isGone = check(n, in, pos, order, isCountLeft, mid);
    // cout << isCountLeft <<" " << l  <<" " << r << " " << mid << " " << isGone
    // << endl;
    if (isGone) {
      if (isCountLeft) {
        l = mid; // find max
      } else {
        r = mid; // find min
      }
    } else {
      if (isCountLeft) {
        r = mid; // find max
      } else {
        l = mid; // find min
      }
    }
  }
  // cout << isCountLeft <<" l = " << l <<" r = " << r <<" " << l << " " << n-r
  // << endl;
  if (isCountLeft) {
    return l + 1;
  } else {
    return n - r;
  }
}

int main() {
  int n, q;
  cin >> n >> q;
  string in;
  cin >> in;
  vector<char> pos(q);
  vector<int> order(q);
  rep(i, q) {
    cin >> pos[i];
    char tmp;
    cin >> tmp;
    if (tmp == 'L')
      order[i] = -1;
    else if (tmp == 'R')
      order[i] = +1;
    else
      assert(0);
  }
  int goneLeft = solve(n, in, pos, order, true);
  int goneRight = solve(n, in, pos, order, false);
  cout << n - goneLeft - goneRight << endl;

  return 0;
}