Problem p03981 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#define loop(i, a, b) for (int i = a; i < b; i++)
#define rep(i, a) loop(i, 0, a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(), in.end()
#define shosu(x) fixed << setprecision(x)
using namespace std;
// kaewasuretyuui
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef pair<int, pii> pip;
typedef vector<pip> vip;
const double PI = acos(-1);
const double EPS = 1e-8;
const int inf = 1e8;
ll MOD1 = 134832894;
ll MOD2 = 183489237;
ll x1 = 52452452;
ll x2 = 34567343;
vector<ll> hash1, hash2, X1, X2;
int n;
int f(int i) {
  set<pair<ll, ll>> se;
  rep(j, n - i) {
    ll a1 = (hash1[i + j + 1] - hash1[j] + MOD1) % MOD1 * X1[n - (i + j + 1)] %
            MOD1;
    ll a2 = (hash2[i + j + 1] - hash2[j] + MOD2) % MOD2 * X2[n - (i + j + 1)] %
            MOD2;
    se.insert(pair<ll, ll>(a1, a2));
  }
  return se.size();
}
int main() {
  string s;
  cin >> s;
  n = s.size();
  X1 = X2 = vector<ll>(n + 1);
  X1[0] = X2[0] = 1;
  rep(i, n) {
    X1[i + 1] = (X1[i] * x1) % MOD1;
    X2[i + 1] = (X2[i] * x2) % MOD2;
  }
  hash1 = hash2 = vector<ll>(n + 1);
  rep(i, n) {
    hash1[i + 1] = (s[i] - 'a') * X1[i + 1];
    hash2[i + 1] = (s[i] - 'a') * X2[i + 1];
  }
  rep(i, n) {
    hash1[i + 1] = (hash1[i + 1] + hash1[i]) % MOD1;
    hash2[i + 1] = (hash2[i + 1] + hash2[i]) % MOD2;
  }
  //	rep(i,n){
  int l = 0, r = n;
  while (r - l > 2) {
    int h1 = l + (r - l) / 3, h2 = l + (r - l) / 3 * 2;
    //		cout<<l<<" "<<h1<<" "<<h2<<" "<<r<<endl;
    int H1 = f(h1), H2 = f(h2);
    //		cout<<H1<<" "<<H2<<endl;
    if (H1 > H2)
      r = h2;
    else
      l = h1;
  }
  int out = 0;
  loop(i, max(0, l - 1), min(r + 1, n)) out = max(out, f(i));
  cout << out << endl;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#define loop(i, a, b) for (int i = a; i < b; i++)
#define rep(i, a) loop(i, 0, a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(), in.end()
#define shosu(x) fixed << setprecision(x)
using namespace std;
// kaewasuretyuui
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef pair<int, pii> pip;
typedef vector<pip> vip;
const double PI = acos(-1);
const double EPS = 1e-8;
const int inf = 1e8;
ll MOD1 = 134832894;
ll MOD2 = 183489237;
ll x1 = 52452452;
ll x2 = 34567343;
vector<ll> hash1, hash2, X1, X2;
int n;
int f(int i) {
  set<pair<ll, ll>> se;
  rep(j, n - i) {
    ll a1 = (hash1[i + j + 1] - hash1[j] + MOD1) % MOD1 * X1[n - (i + j + 1)] %
            MOD1;
    ll a2 = (hash2[i + j + 1] - hash2[j] + MOD2) % MOD2 * X2[n - (i + j + 1)] %
            MOD2;
    se.insert(pair<ll, ll>(a1, a2));
  }
  return se.size();
}
int main() {
  string s;
  cin >> s;
  n = s.size();
  X1 = X2 = vector<ll>(n + 1);
  X1[0] = X2[0] = 1;
  rep(i, n) {
    X1[i + 1] = (X1[i] * x1) % MOD1;
    X2[i + 1] = (X2[i] * x2) % MOD2;
  }
  hash1 = hash2 = vector<ll>(n + 1);
  rep(i, n) {
    hash1[i + 1] = (s[i] - 'a') * X1[i + 1];
    hash2[i + 1] = (s[i] - 'a') * X2[i + 1];
  }
  rep(i, n) {
    hash1[i + 1] = (hash1[i + 1] + hash1[i]) % MOD1;
    hash2[i + 1] = (hash2[i + 1] + hash2[i]) % MOD2;
  }
  //	rep(i,n){
  int l = 0, r = n;
  while (r - l > 2) {
    int h1 = l + (r - l) / 3, h2 = l + (r - l) / 3 * 2;
    //		cout<<l<<" "<<h1<<" "<<h2<<" "<<r<<endl;
    int H1 = f(h1), H2 = f(h2);
    //		cout<<H1<<" "<<H2<<endl;
    if (H1 > H2)
      r = h2;
    else
      l = h1;
  }
  int out = 0;
  loop(i, l, r) out = max(out, f(i));
  cout << out << endl;
}