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

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define ll long long
#define ld long double
#define EPS 0.0000000001
#define INF 1e9
#define LINF (ll) INF *INF
#define MOD 1000000007
#define rep(i, n) for (int i = 0; i < (n); i++)
#define loop(i, a, n) for (int i = a; i < (n); i++)
#define all(in) in.begin(), in.end()
#define shosu(x) fixed << setprecision(x)

#define int ll //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef vector<pii> vp;

int gcd(int a, int b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
int lcm(int a, int b) { return a / gcd(a, b) * b; }

class RollingHash {
private:
  int M = 1e9 + 7;
  int base = 1213;
  string str;
  int n;
  vector<int> pow, sum;

  void build() {
    n = str.size();
    sum = pow = vector<int>(n + 1);
    sum[0] = 0;
    pow[0] = 1;
    for (int i = 0; i < n; i++) {
      sum[i + 1] = (str[i] + sum[i] * base) % M;
      pow[i + 1] = pow[i] * base % M;
    }
  }

public:
  RollingHash() {}
  RollingHash(string in) {
    str = in;
    build();
  }
  RollingHash(string in, int p, int mod) {
    M = mod;
    base = p;
    str = in;
    build();
  }

  int calc(int l, int r) { //[l,r)のハッシュ値を計算
    int len = r - l;
    int ret = sum[r] + M;
    ret -= sum[l] * pow[len] % M;
    return ret % M;
  }
};

signed main(void) {
  string s, t;
  while (cin >> s) {
    cin >> t;
    RollingHash rs(s);
    RollingHash rt(t);
    int n = s.size();
    int m = t.size();
    int ok = 0, ng = min(n, m) + 1;
    while (ng - ok > 1) {
      int mid = (ok + ng) / 2;
      set<int> st;
      rep(i, n - mid + 1) { st.insert(rs.calc(i, i + mid)); }
      bool c = false;
      rep(i, m - mid + 1) {
        if (st.count(rt.calc(i, i + mid)))
          c = true;
      }
      if (c)
        ok = mid;
      else
        ng = mid;
    }
    cout << ok << endl;
  }
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define ll long long
#define ld long double
#define EPS 0.0000000001
#define INF 1e9
#define LINF (ll) INF *INF
#define MOD 1000000007
#define rep(i, n) for (int i = 0; i < (n); i++)
#define loop(i, a, n) for (int i = a; i < (n); i++)
#define all(in) in.begin(), in.end()
#define shosu(x) fixed << setprecision(x)

#define int ll //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef vector<pii> vp;

int gcd(int a, int b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
int lcm(int a, int b) { return a / gcd(a, b) * b; }

class RollingHash {
private:
  int M = 1e9 + 7;
  int base = 1213;
  string str;
  int n;
  vector<int> pow, sum;

  void build() {
    n = str.size();
    sum = pow = vector<int>(n + 1);
    sum[0] = 0;
    pow[0] = 1;
    for (int i = 0; i < n; i++) {
      sum[i + 1] = (str[i] + sum[i] * base) % M;
      pow[i + 1] = pow[i] * base % M;
    }
  }

public:
  RollingHash() {}
  RollingHash(string in) {
    str = in;
    build();
  }
  RollingHash(string in, int p, int mod) {
    M = mod;
    base = p;
    str = in;
    build();
  }

  int calc(int l, int r) { //[l,r)のハッシュ値を計算
    int len = r - l;
    int ret = sum[r] + M;
    ret -= sum[l] * pow[len] % M;
    return ret % M;
  }
};

signed main(void) {
  string s, t;
  while (cin >> s) {
    cin >> t;
    RollingHash rs(s);
    RollingHash rt(t);
    int ans = 0;
    int n = s.size();
    int m = t.size();
    rep(i, n) rep(j, m) if (s[i] == t[j]) {
      int nn = n - i, mm = m - j;
      int ok = 1, ng = min(nn, mm) + 1;
      while (ng - ok > 1) {
        int mid = (ok + ng) / 2;
        if (rs.calc(i, i + mid) == rt.calc(j, j + mid))
          ok = mid;
        else
          ng = mid;
      }
      ans = max(ans, ok);
    }
    cout << ans << endl;
  }
}