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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

string s;
int i;

/*
 * expr   ::= term [ "-" term]*
 * term   ::= number | "S<" expr ">"
 * number ::= [0-9]+
 */

ll expr();
ll term();
ll number();

ll expr() {
  ll val = term();
  while (s[i] == '-') {
    i++;
    val = val >> min(term(), 32ll);
  }
  return val;
}
ll term() {
  if (isdigit(s[i]))
    return number();
  i += 2;
  ll val = expr();
  val = val * val % 1'000'000'007;
  i++;
  return val;
}
ll number() {
  string val;
  while (isdigit(s[i])) {
    val.push_back(s[i++]);
  }
  return stoll(val);
}

bool input() { return getline(cin, s) and s != "#"; }

ll solve() {
  for (auto c = s.begin(); c != s.end();) {
    if (*c == ' ')
      c = s.erase(c);
    else
      c++;
  }
  for (int i = 2; i < s.size(); i++) {
    if (isdigit(s[i]) or s[i] == 'S') {
      if (s[i - 1] == '>' and s[i - 2] == '>') {
        s[i - 1] = '-';
        s.erase(s.begin() + i - 2);
      }
    }
  }
  i = 0;
  return expr();
}

int main(void) {
  while (input()) {
    cout << solve() << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define INF 1e9
#define EPS 1e-9
#define MOD (ll)(1e9 + 7)
void put(string d) {}
template <class H, class... T> void put(string d, H &h, T &...t) {
  cout << h;
  if (sizeof...(t))
    cout << d;
  put(d, t...);
}
template <class T> void puti(T &a, string d = " ") {
  bool f = 1;
  for (auto &_ : a)
    cout << (exchange(f, 0) ? "" : d) << _;
  cout << endl;
}
template <class T> void putii(T &a, string d = " ") {
  for (auto &_ : a)
    puti(_, d);
}

template <class T> string bitstr(T x) {
  return typeid(T) == typeid(int) ? bitset<32>(x).to_string('_', '#')
                                  : bitset<64>(x).to_string();
}
template <class T> int bitcnt(T x) {
  return typeid(T) == typeid(int) ? __builtin_popcount(x)
                                  : __builtin_popcountll(x);
}
template <class T> int bitdig(T x) {
  return x ? typeid(T) == typeid(int) ? 32 - __builtin_clz(x)
                                      : 64 - __builtin_clzll(x)
           : 0;
}
template <class T> int bitpow(T x) {
  return x ? typeid(T) == typeid(int) ? __builtin_ctz(x) : __builtin_ctzll(x)
           : 0;
}

ll solve(string s) {
  s += "_";
  stack<stack<ll>> num;
  stack<bool> sft;
  string n = "";
  num.emplace();
  sft.push(false);
  for (int i = 0; i < s.size(); i++) {
    /*
    cout<<"========="<<endl;
    cout<<s[i]<<endl;
    cout<<"num:"<<num.size()<<endl;
    cout<<"sft:"<<sft.size()<<"("<<(sft.top()?"true":"false")<<")"<<endl;
    */
    if (!isdigit(s[i])) {
      if (n != "") {
        if (sft.top()) {
          num.top().top() >>= min(stoll(n), 32ll);
          sft.top() = false;
        } else {
          num.top().push(stoll(n));
        }
        n = "";
      }
    }
    if (s[i] == '<') {
      num.emplace();
      sft.push(false);
    } else if (s[i] == '-') {
      sft.top() = true;
      // cout<<"shift"<<endl;
    } else if (s[i] == '>') {
      // cout<<num.top().top()<<"("<<sft.top()<<")"<<endl;
      ll r = num.top().top();
      r = r * r % MOD;
      num.pop();
      sft.pop();
      num.top().push(r);
    } else if (s[i] != ' ') {
      n += s[i];
      // cout<<"n:"<<n<<endl;
    }
  }
  return num.top().top();
}

int main() {
  string s;
  while (getline(cin, s), s != "#") {
    for (auto c = s.find_first_of(" "); c != -1; c = s.find_first_of(" ")) {
      s.erase(c, 1);
    }
    for (int i = 1; i < s.size() - 1; i++) {
      if (s[i - 1] == '>' and s[i] == '>' and s[i + 1] != '<' and
          s[i + 1] != '>') {
        s.replace(i - 1, 2, "-");
      }
    }
    for (auto c = s.find_first_of("S"); c != -1; c = s.find_first_of("S")) {
      s.erase(c, 1);
    }
    for (auto c = s.find("-0"); c != -1; c = s.find("-0")) {
      s.erase(c, 2);
    }
    int p = 0;
    rep(i, s.size() - 1) {
      if (s[i] == '<')
        p++;
      if (s[i] == '>')
        p--;
      if (p < 0) {
        p = 0;
        s[i] = '-';
      }
    }
    // cout<<s<<endl;
    cout << solve(s) << endl;
  }
  return 0;
}