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

#pragma GCC optimize("O3")
#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;

using namespace std;

typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> pr;
typedef pair<LL, LL> lpr;
typedef pair<double, double> dpr;
typedef pair<long double, long double> ldpr;
typedef double db;
typedef long double ld;
// typedef complex<double> cp;
// typedef pair<ld,ld> pt;

#define dbgs(x) #x << " = " << x
#define dbgs2(x, y) dbgs(x) << ", " << dbgs(y)
#define dbgs3(x, y, z) dbgs2(x, y) << ", " << dbgs(z)
#define dbgs4(w, x, y, z) dbgs3(w, x, y) << ", " << dbgs(z)

#define mst(s, x) memset(s, x, sizeof(s))
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define mp make_pair
#define all(x) x.begin(), x.end()
#define unq(x) x.erase(unique(x.begin(), x.end()), x.end())
#define rg register
#define fp(i, a, b) for (rg int i = (a), I = (b) + 1; i < I; ++i)
#define fd(i, a, b) for (rg int i = (a), I = (b)-1; i > I; --i)
#define ub upper_bound
#define lb lower_bound
#define bitcount __builtin_popcount
#define sqr(x) ((x) * (x))

#define go(u) for (rg int i = pre[u], v = e[i].v; i; i = e[i].next, v = e[i].v)
#define gow(u)                                                                 \\
  for (rg LL i = pre[u], v = e[i].v, w = e[i].w; i;                            \\
       i = e[i].next, v = e[i].v, w = e[i].w)
#define EDGE(N, M)                                                             \\
  struct edge {                                                                \\
    int u, v, w, next;                                                         \\
  } e[M];                                                                      \\
  int pre[N], edge_cnt = 0;                                                    \\
  void addedge(int u, int v, int w = 0) {                                      \\
    edge_cnt = edge_cnt + 1, e[edge_cnt].u = u, e[edge_cnt].v = v,             \\
    e[edge_cnt].w = w, e[edge_cnt].next = pre[u], pre[u] = edge_cnt;           \\
  }
#define CLEAR_EDGE(N)                                                          \\
  { edge_cnt = 0, memset(pre, 0, sizeof(int) * (N + 1)); }

#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')

#define MC                                                                     \\
  int _CASE;                                                                   \\
  scanf("%d", &_CASE);                                                         \\
  fp(case_num, 1, _CASE)

const int next_x[8] = {0, 1, -1, 0, 1, 1, -1, -1};
const int next_y[8] = {1, 0, 0, -1, 1, -1, -1, 1};
const int inf = 1e9 + 5; // 7;
const LL linf = 1e18 + 5;
const double PI = acos(-1.0);

const int MAXN = 2e5 + 5;
const int N = 200 * 200 * 2 + 5;
const int fix = 500 * 500 + 5;

#define mid ((l + r) / 2)
#define ls (cnt << 1)
#define rs (cnt << 1 | 1)

// #define ls ch[x][0]
// #define rs ch[x][1]

/*----------head----------*/

struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};
// unordered_map<long long, int, custom_hash> safe_map;
// gp_hash_table<long long, int, custom_hash> safe_hash_table;

ULL base = 13331;
int n;
string s[MAXN];
vector<ULL> h[MAXN];
vector<ULL> v[26], t;
gp_hash_table<ULL, int, custom_hash> vis;
LL ans = 0;
int cnt[26];
int work() {}

// 小数 二分/三分 注意break条件
// 浮点运算 sqrt(a^2-b^2) 可用 sqrt(a+b)*sqrt(a-b) 代替，避免精度问题
// long double -> %Lf 别用C11 (C14/16)
// 控制位数 cout << setprecision(10) << ans;
// reverse vector 注意判空 不然会re
// 分块注意维护块上标记 来更新块内数组a[]
// vector+lower_bound常数 < map/set
// map.find不会创建新元素 map[]会 注意空间
// 别对指针用memset
// 用位运算表示2^n注意加LL 1LL<<20
// 注意递归爆栈
// 注意边界
// 注意memset 多组会T

// #define ONLINE_JUDGE

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef ONLINE_JUDGE
  // freopen("triatrip.in", "r",stdin );
  // freopen("triatrip.out","w",stdout);
#endif // ONLINE_JUDGE
#ifndef ONLINE_JUDGE
  int size = 512 << 20; // 512MB
  char *p = (char *)malloc(size) + size;
  __asm__("movl %0, %%esp\\n" ::"r"(p));
  freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
#endif
  cin >> n;
  fp(i, 1, n) {
    cin >> s[i];
    h[i].resize(s[i].size() + 1);
    fd(j, s[i].size() - 1, 0) h[i][j] = h[i][j + 1] * base + s[i][j];
    mst(cnt, 0);
    fp(j, 0, s[i].size()) {
      fp(k, 0, 25) if (cnt[k]) v[k].pb(h[i][j]);
      if (j < s[i].size())
        cnt[s[i][j] - 'a'] = 1;
    }
    t.pb(h[i][0]);
  }
  sort(all(t));
  fp(i, 0, 25) sort(all(v[i]));
  fp(i, 1, n) {
    int c = s[i][0] - 'a';
    ans += ub(all(v[c]), h[i][1]) - lb(all(v[c]), h[i][1]);
  }
  int num = 1;
  fp(i, 1, t.size()) if (i == t.size() || t[i] != t[i - 1]) ans -=
      1LL * num * (num - 1) / 2 + num,
      num = 1;
  else num++;
  return 0 * printf("%lld\\n", ans);
#ifndef ONLINE_JUDGE
  cout << "time:" << clock() << "ms" << endl;
  freopen("CON", "r", stdin);
  freopen("CON", "w", stdout);
  system("pause");
  fflush(stdout);
#endif
  return 0;
}


Error: TLE

Fixed submission:

#pragma GCC optimize("O3")
#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;

using namespace std;

typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> pr;
typedef pair<LL, LL> lpr;
typedef pair<double, double> dpr;
typedef pair<long double, long double> ldpr;
typedef double db;
typedef long double ld;
// typedef complex<double> cp;
// typedef pair<ld,ld> pt;

#define dbgs(x) #x << " = " << x
#define dbgs2(x, y) dbgs(x) << ", " << dbgs(y)
#define dbgs3(x, y, z) dbgs2(x, y) << ", " << dbgs(z)
#define dbgs4(w, x, y, z) dbgs3(w, x, y) << ", " << dbgs(z)

#define mst(s, x) memset(s, x, sizeof(s))
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define mp make_pair
#define all(x) x.begin(), x.end()
#define unq(x) x.erase(unique(x.begin(), x.end()), x.end())
#define rg register
#define fp(i, a, b) for (rg int i = (a), I = (b) + 1; i < I; ++i)
#define fd(i, a, b) for (rg int i = (a), I = (b)-1; i > I; --i)
#define ub upper_bound
#define lb lower_bound
#define bitcount __builtin_popcount
#define sqr(x) ((x) * (x))

#define go(u) for (rg int i = pre[u], v = e[i].v; i; i = e[i].next, v = e[i].v)
#define gow(u)                                                                 \\
  for (rg LL i = pre[u], v = e[i].v, w = e[i].w; i;                            \\
       i = e[i].next, v = e[i].v, w = e[i].w)
#define EDGE(N, M)                                                             \\
  struct edge {                                                                \\
    int u, v, w, next;                                                         \\
  } e[M];                                                                      \\
  int pre[N], edge_cnt = 0;                                                    \\
  void addedge(int u, int v, int w = 0) {                                      \\
    edge_cnt = edge_cnt + 1, e[edge_cnt].u = u, e[edge_cnt].v = v,             \\
    e[edge_cnt].w = w, e[edge_cnt].next = pre[u], pre[u] = edge_cnt;           \\
  }
#define CLEAR_EDGE(N)                                                          \\
  { edge_cnt = 0, memset(pre, 0, sizeof(int) * (N + 1)); }

#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')

#define MC                                                                     \\
  int _CASE;                                                                   \\
  scanf("%d", &_CASE);                                                         \\
  fp(case_num, 1, _CASE)

const int next_x[8] = {0, 1, -1, 0, 1, 1, -1, -1};
const int next_y[8] = {1, 0, 0, -1, 1, -1, -1, 1};
const int inf = 1e9 + 5; // 7;
const LL linf = 1e18 + 5;
const double PI = acos(-1.0);

const int MAXN = 1e6 + 5;
const int N = 200 * 200 * 2 + 5;
const int fix = 500 * 500 + 5;

#define mid ((l + r) / 2)
#define ls (cnt << 1)
#define rs (cnt << 1 | 1)

// #define ls ch[x][0]
// #define rs ch[x][1]

/*----------head----------*/

ULL base = 1331;
int n, cnt[26];
string s[MAXN];
vector<ULL> h[MAXN];
LL ans = 0;
vector<pair<int, ULL>> req;
vector<ULL> v;
char t[MAXN];
// 小数 二分/三分 注意break条件
// 浮点运算 sqrt(a^2-b^2) 可用 sqrt(a+b)*sqrt(a-b) 代替，避免精度问题
// long double -> %Lf 别用C11 (C14/16)
// 控制位数 cout << setprecision(10) << ans;
// reverse vector 注意判空 不然会re
// 分块注意维护块上标记 来更新块内数组a[]
// vector+lower_bound常数 < map/set
// map.find不会创建新元素 map[]会 注意空间
// 别对指针用memset
// 用位运算表示2^n注意加LL 1LL<<20
// 注意递归爆栈
// 注意边界
// 注意memset 多组会T

// #define ONLINE_JUDGE

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef ONLINE_JUDGE
  // freopen("triatrip.in", "r",stdin );
  // freopen("triatrip.out","w",stdout);
#endif // ONLINE_JUDGE
#ifndef ONLINE_JUDGE
  int size = 512 << 20; // 512MB
  char *p = (char *)malloc(size) + size;
  __asm__("movl %0, %%esp\\n" ::"r"(p));
  freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
#endif
  cin >> n;
  fp(i, 1, n) {
    cin >> s[i];
    h[i].resize(s[i].size() + 1);
    fd(j, s[i].size() - 1, 0) h[i][j] = h[i][j + 1] * base + s[i][j];
    // mst(cnt,0);
    // fp(j,0,s[i].size())
    // {
    //     fp(k,0,25)if(cnt[k])v[k][h[i][j]]++;
    //     if(j<s[i].size())cnt[s[i][j]-'a']=1;
    // }
    req.pb({s[i][0] - 'a', h[i][1]}), v.pb(h[i][0]);
  }
  sort(all(req));
  fp(i, 1, n) {
    mst(cnt, 0);
    fp(j, 0, s[i].size()) {
      fp(k, 0, 25) if (cnt[k]) {
        pair<int, ULL> cur = {k, h[i][j]};
        ans += ub(all(req), cur) - lb(all(req), cur);
      }
      if (j < s[i].size())
        cnt[s[i][j] - 'a'] = 1;
    }
  }
  sort(all(v));
  int num = 1;
  fp(i, 1, v.size()) if (i == v.size() || v[i] != v[i - 1]) ans -=
      1LL * num * (num - 1) / 2 + num,
      num = 1;
  else num++;
  // fp(i,1,n)ans+=v[s[i][0]-'a'][h[i][1]]-1-(vis[h[i][0]]++);
  printf("%lld\\n", ans);
#ifndef ONLINE_JUDGE
  cout << "time:" << clock() << "ms" << endl;
  freopen("CON", "r", stdin);
  freopen("CON", "w", stdout);
  system("pause");
  fflush(stdout);
#endif
  return 0;
}