Problem p02913 (C++)

Buggy submission (status: Time Limit Exceeded):
#define _CRT_SECURE_NO_WARNINGS
#define MOD 1000000007
#define MOD2 998244353
#define INF 100000000
// #define MOD 922337203685419LL
#include <algorithm>
#include <bitset>
#include <chrono>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

typedef pair<int, int> pi;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vector<int>> vvi;
typedef vector<vector<ll>> vvll;
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RFOR(i, a, b) for (int i = (a); i > (b); i--)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, n - 1, -1)
#define ALL(obj) (obj).begin(), (obj).end()

inline ll madd(ll a, ll b) {
  a %= MOD;
  b %= MOD;
  return (a + b) % MOD;
}
inline ll msub(ll a, ll b) {
  a %= MOD;
  b %= MOD;
  a += MOD;
  return (a - b) % MOD;
}
inline ll mmul(ll a, ll b) {
  a %= MOD;
  b %= MOD;
  return (a * b) % MOD;
}
inline ll mpow(ll a, ll r) {
  long long res = 1;
  while (r > 0) {
    if (r & 1)
      res = res * a % MOD;
    a = a * a % MOD;
    r >>= 1;
  }
  return res;
}
inline ll minv(ll a) {
  a %= MOD;
  ll b = MOD, u = 0, v = 1;
  while (a) {
    ll t = b / a;
    b -= t * a;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  if (u < 0)
    u += MOD;
  return u;
}
inline ll mdiv(ll a, ll b) {
  a %= MOD;
  a *= minv(b);
  return a % MOD;
}

// ll fact[]
// inline ll combi(int a, int b) {
//	return mmul(fact[a], mmul(fact_inv[b], fact_inv[a - b]));
// }

struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};

struct edge {
  ll to, cost;
};

int main() {
  ll power[2501];
  power[0] = 1;
  REP(i, 2500) power[i + 1] = (power[i] * 29) % MOD;

  ll power2[2501];
  power2[0] = 1;
  REP(i, 2500) power2[i + 1] = (power2[i] * 29) % MOD2;

  int n;
  cin >> n;
  char s[5001];
  scanf("%s", s);

  vll hash_list;
  ll ha = 0;
  hash_list.push_back(0);
  REP(i, n) {
    ha *= 29;
    ha += s[i] - 'a' + 2;
    ha %= MOD;
    hash_list.push_back(ha);
  }

  vll hash_list2;
  ll ha2 = 0;
  hash_list2.push_back(0);
  REP(i, n) {
    ha2 *= 29;
    ha2 += s[i] - 'a' + 2;
    ha2 %= MOD2;
    hash_list2.push_back(ha2);
  }

  RFOR(j, n / 2, 0) {
    map<ll, int> ma;
    REP(i, n - j + 1) {
      ll x = (hash_list[i] * power[j]) % MOD;
      x = (hash_list[i + j] + MOD - x) % MOD;
      if (ma.find(x) == ma.end())
        ma[x] = i;
      else if (i >= ma[x] + j) {
        ll xx = (hash_list2[i] * power2[j]) % MOD2;
        xx = (hash_list2[i + j] + MOD2 - xx) % MOD2;
        ll xxx = (hash_list2[ma[x]] * power2[j]) % MOD2;
        xxx = (hash_list2[ma[x] + j] + MOD2 - xxx) % MOD2;
        if (xx == xxx) {
          cout << j;
          return 0;
        }
      }
    }
  }

  cout << "0";
  return 0;
}


Fixed submission:
#define _CRT_SECURE_NO_WARNINGS
#define MOD 1000000007
#define MOD2 998244353
#define INF 100000000
// #define MOD 922337203685419LL
#include <algorithm>
#include <bitset>
#include <chrono>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

typedef pair<int, int> pi;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vector<int>> vvi;
typedef vector<vector<ll>> vvll;
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RFOR(i, a, b) for (int i = (a); i > (b); i--)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, n - 1, -1)
#define ALL(obj) (obj).begin(), (obj).end()

inline ll madd(ll a, ll b) {
  a %= MOD;
  b %= MOD;
  return (a + b) % MOD;
}
inline ll msub(ll a, ll b) {
  a %= MOD;
  b %= MOD;
  a += MOD;
  return (a - b) % MOD;
}
inline ll mmul(ll a, ll b) {
  a %= MOD;
  b %= MOD;
  return (a * b) % MOD;
}
inline ll mpow(ll a, ll r) {
  long long res = 1;
  while (r > 0) {
    if (r & 1)
      res = res * a % MOD;
    a = a * a % MOD;
    r >>= 1;
  }
  return res;
}
inline ll minv(ll a) {
  a %= MOD;
  ll b = MOD, u = 0, v = 1;
  while (a) {
    ll t = b / a;
    b -= t * a;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  if (u < 0)
    u += MOD;
  return u;
}
inline ll mdiv(ll a, ll b) {
  a %= MOD;
  a *= minv(b);
  return a % MOD;
}

// ll fact[]
// inline ll combi(int a, int b) {
//	return mmul(fact[a], mmul(fact_inv[b], fact_inv[a - b]));
// }

struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};

struct edge {
  ll to, cost;
};

int main() {
  ll power[2501];
  power[0] = 1;
  REP(i, 2500) power[i + 1] = (power[i] * 29) % MOD;

  ll power2[2501];
  power2[0] = 1;
  REP(i, 2500) power2[i + 1] = (power2[i] * 29) % MOD2;

  int n;
  cin >> n;
  char s[5001];
  scanf("%s", s);

  vll hash_list;
  ll ha = 0;
  hash_list.push_back(0);
  REP(i, n) {
    ha *= 29;
    ha += s[i] - 'a' + 2;
    ha %= MOD;
    hash_list.push_back(ha);
  }

  vll hash_list2;
  ll ha2 = 0;
  hash_list2.push_back(0);
  REP(i, n) {
    ha2 *= 29;
    ha2 += s[i] - 'a' + 2;
    ha2 %= MOD2;
    hash_list2.push_back(ha2);
  }

  RFOR(j, n / 2, 0) {
    unordered_map<ll, int> ma;
    REP(i, n - j + 1) {
      ll x = (hash_list[i] * power[j]) % MOD;
      x = (hash_list[i + j] + MOD - x) % MOD;
      if (ma.find(x) == ma.end())
        ma[x] = i;
      else if (i >= ma[x] + j) {
        ll xx = (hash_list2[i] * power2[j]) % MOD2;
        xx = (hash_list2[i + j] + MOD2 - xx) % MOD2;
        ll xxx = (hash_list2[ma[x]] * power2[j]) % MOD2;
        xxx = (hash_list2[ma[x] + j] + MOD2 - xxx) % MOD2;
        if (xx == xxx) {
          cout << j;
          return 0;
        }
      }
    }
  }

  cout << "0";
  return 0;
}