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

#include <bits/stdc++.h>

using namespace std;

#define FOR(i, x, y) for (int i = (x); i < (y); ++i)
#define REP(i, x, y) for (int i = (x); i <= (y); ++i)
#define PB push_back
#define MP make_pair
#define PH push
#define fst first
#define snd second
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<int, int> pii;

const int maxn = 2e5 + 5;

int n;
ll ans, ans2;
string s[maxn];
vector<ull> p[maxn];

class HashMap {
public:
  static const int MOD = 1e6 + 3;
  int tot;
  int head[MOD], nxt[maxn], dat[maxn];
  ull val[maxn];
  HashMap() {
    tot = 0;
    memset(head, -1, sizeof(head));
  }
  inline void update(ull h) {
    int v = h % MOD;
    for (int i = head[v]; ~i; i = nxt[i])
      if (val[i] == h) {
        ++dat[i];
        return;
      }
    nxt[tot] = head[v];
    dat[tot] = 1;
    val[tot] = h;
    head[v] = tot++;
    return;
  }
  inline int query(ull h) {
    int v = h % MOD;
    for (int i = head[v]; ~i; i = nxt[i])
      if (val[i] == h)
        return dat[i];
    return 0;
  }
} mp;

int main() {
  cin >> n;
  FOR(i, 0, n) {
    cin >> s[i];
    reverse(s[i].begin(), s[i].end());
  }
  FOR(i, 0, n) {
    ull h = 0;
    FOR(j, 0, s[i].size()) {
      (h *= 31) += s[i][j] - 'a' + 1;
      p[i].PB(h);
    }
    //		printf("i = %d h = %llu\\n", i, h);
    mp.update(h);
  }
  FOR(i, 0, n) {
    int msk = 0;
    for (int j = s[i].size() - 1; j >= 0; --j) {
      FOR(k, 0, 26) if (msk >> k & 1) {
        if (j < s[i].size() - 2)
          ans += mp.query(p[i][j] * 31 + (k + 1));
      }
      msk |= 1 << (s[i][j] - 'a');
    }
    FOR(k, 0, 26) if (msk >> k & 1) {
      if (s[i].size() > 1)
        ans += mp.query(k + 1);
    }
    ans2 += mp.query(p[i][s[i].size() - 1]);
    --ans2;
  }
  printf("%lld\\n", ans + ans2 / 2);
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define FOR(i, x, y) for (int i = (x); i < (y); ++i)
#define REP(i, x, y) for (int i = (x); i <= (y); ++i)
#define PB push_back
#define MP make_pair
#define PH push
#define fst first
#define snd second
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<int, int> pii;

const int maxn = 2e5 + 5;

int n;
ll ans, ans2;
string s[maxn];
vector<ull> p[maxn];
unordered_map<ull, int> mp;

int main() {
  cin >> n;
  FOR(i, 0, n) {
    cin >> s[i];
    reverse(s[i].begin(), s[i].end());
  }
  FOR(i, 0, n) {
    ull h = 0;
    FOR(j, 0, s[i].size()) {
      (h *= 31) += s[i][j] - 'a' + 1;
      p[i].PB(h);
    }
    //		printf("i = %d h = %llu\\n", i, h);
    ++mp[h];
  }
  FOR(i, 0, n) {
    int msk = 0;
    for (int j = s[i].size() - 1; j >= 0; --j) {
      FOR(k, 0, 26) if (msk >> k & 1) {
        if (j < s[i].size() - 2)
          ans += mp[p[i][j] * 31 + (k + 1)];
      }
      msk |= 1 << (s[i][j] - 'a');
      //			printf("i = %d j = %d ans = %lld\\n", i, j, ans);
    }
    FOR(k, 0, 26) if (msk >> k & 1) {
      //			printf("k = %d %d\\n", k, mp[k + 1]);
      if (s[i].size() > 1)
        ans += mp[k + 1];
    }
    ans2 += mp[p[i][s[i].size() - 1]];
    --ans2;
  }
  printf("%lld\\n", ans + ans2 / 2);
  return 0;
}