Problem p02913 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repp(i, a, b) for (int i = a; i <= (b); ++i)
#define repr(i, a, b) for (int i = a; i >= (b); --i)
#define bit(n) (1LL << (n))
#define sz(x) ((int)(x).size())
typedef long long ll;
const int INF = 1001001001;
const ll LINF = 1001001001001001001ll;
const int MOD = 1000000007;

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

typedef unsigned long long ull;
unsigned int BASE;

void init_RH() {
  srand(time(NULL));
  BASE = rand() % RAND_MAX + 129;
}

struct RollingHash {
  const ull MASK30 = (1ULL << 30) - 1;
  const ull MASK31 = (1ULL << 31) - 1;
  const ull MODrh = (1ULL << 61) - 1;
  const ull POSITIVIZER = MODrh * ((1ULL << 3) - 1);
  unsigned int Base;
  vector<ull> hash;
  vector<ull> powMemo;

  RollingHash(string s, unsigned int BASE) {
    Base = BASE;
    powMemo = vector<ull>(sz(s) + 1);
    powMemo[0] = 1;
    repp(i, 1, sz(powMemo) - 1) {
      powMemo[i] = CalcMod(Mul(powMemo[i - 1], Base));
    }
    hash = vector<ull>(sz(s) + 1);
    rep(i, sz(s)) { hash[i + 1] = CalcMod(Mul(hash[i], Base) + s[i]); }
  }

  ull Slice(int begin, int length) {
    return CalcMod(hash[begin + length] + POSITIVIZER -
                   Mul(hash[begin], powMemo[length]));
  }

  ull Mul(ull l, ull r) {
    ull lu = l >> 31;
    ull ld = l & MASK31;
    ull ru = r >> 31;
    ull rd = r & MASK31;
    ull middleBit = ld * ru + lu * rd;
    return ((lu * ru) << 1) + ld * rd + ((middleBit & MASK30) << 31) +
           (middleBit >> 30);
  }

  ull CalcMod(ull val) {
    val = (val & MODrh) + (val >> 61);
    if (val > MODrh)
      val -= MODrh;
    return val;
  }
};

int main() {
  init_RH();
  int N;
  cin >> N;
  string S;
  cin >> S;

  RollingHash R(S, BASE);

  int ans = 0;
  repp(len, 1, N) {
    map<ull, int> m;
    rep(i, N - len + 1) {
      ull hash = R.Slice(i, len);
      if (m.find(hash) == m.end()) {
        m[hash] = i;
      } else {
        if (i - m[hash] >= len)
          ans = len;
      }
    }
  }

  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repp(i, a, b) for (int i = a; i <= (b); ++i)
#define repr(i, a, b) for (int i = a; i >= (b); --i)
#define bit(n) (1LL << (n))
#define sz(x) ((int)(x).size())
typedef long long ll;
const int INF = 1001001001;
const ll LINF = 1001001001001001001ll;
const int MOD = 1000000007;

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

typedef unsigned long long ull;
unsigned int BASE;

void init_RH() {
  srand(time(NULL));
  BASE = rand() % RAND_MAX + 129;
}

struct RollingHash {
  const ull MASK30 = (1ULL << 30) - 1;
  const ull MASK31 = (1ULL << 31) - 1;
  const ull MODrh = (1ULL << 61) - 1;
  const ull POSITIVIZER = MODrh * ((1ULL << 3) - 1);
  unsigned int Base;
  vector<ull> hash;
  vector<ull> powMemo;

  RollingHash(string s, unsigned int BASE) {
    Base = BASE;
    powMemo = vector<ull>(sz(s) + 1);
    powMemo[0] = 1;
    repp(i, 1, sz(powMemo) - 1) {
      powMemo[i] = CalcMod(Mul(powMemo[i - 1], Base));
    }
    hash = vector<ull>(sz(s) + 1);
    rep(i, sz(s)) { hash[i + 1] = CalcMod(Mul(hash[i], Base) + s[i]); }
  }

  ull Slice(int begin, int length) {
    return CalcMod(hash[begin + length] + POSITIVIZER -
                   Mul(hash[begin], powMemo[length]));
  }

  ull Mul(ull l, ull r) {
    ull lu = l >> 31;
    ull ld = l & MASK31;
    ull ru = r >> 31;
    ull rd = r & MASK31;
    ull middleBit = ld * ru + lu * rd;
    return ((lu * ru) << 1) + ld * rd + ((middleBit & MASK30) << 31) +
           (middleBit >> 30);
  }

  ull CalcMod(ull val) {
    val = (val & MODrh) + (val >> 61);
    if (val > MODrh)
      val -= MODrh;
    return val;
  }
};

int main() {
  init_RH();
  int N;
  cin >> N;
  string S;
  cin >> S;

  RollingHash R(S, BASE);

  int ans = 0;
  rep(i, N) {
    repp(j, i, N - 1) {
      while ((ans < j - i) && (j + ans < N) &&
             R.Slice(i, ans + 1) == R.Slice(j, ans + 1))
        ans++;
    }
  }

  cout << ans << endl;
}