Problem p03974 (C++)

Buggy submission (status: Runtime Error):
/*************************************************************************

       Author:            palayutm
       Created Time :     Mon 10 Oct 2016 12:13:01 PM CST

       File Name:         e.cc
       Description:       new style, new life

 ************************************************************************/
#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;

const ull base = 1e9 + 7;

const int B = 3;

int ch[400005][26], cnt = 1;
vector<int> vec[400006];
vector<string> vstr, vv;
vector<vector<ull>> key;
int cl[B + 100][B + 100];
int idx[100005];
bool tx[256][267];
int hh[400005];

void insert(char *s, int id) {
  int now = 0;
  for (int i = 0; s[i]; i++) {
    int c = s[i] - 'a';
    if (!ch[now][c]) {
      ch[now][c] = cnt++;
    }
    now = ch[now][c];
    vec[now].push_back(id);
  }
  hh[now] = id;
}

char s[400005];

int solve(int k, const string &t) {
  string &s = vv[k - 1];
  for (int i = 0; i < 26; i++) {
    for (int j = i + 1; j < 26; j++) {
      tx[t[i]][t[j]] = 1;
      tx[t[j]][t[i]] = 0;
    }
  }
  int ans = 0;
  int now = 0;
  for (int i = 0; i < min(B, (int)s.size()); i++) {
    if (hh[now] >= 0) {
      ans++;
    }
    for (int j = 0; j < 26; j++) {
      if (t[j] == s[i]) {
        now = ch[now][s[i] - 'a'];
        break;
      }
      int c = t[j] - 'a';
      int num = vec[ch[now][c]].size();
      ans += num;
    }
  }
  if (s.size() < B) {
    return ans;
  }
  sort(vec[now].begin(), vec[now].end(), [](const int xx, const int yy) {
    int x = idx[xx], y = idx[yy];
    if (cl[x][y] == -1) {
      return vstr[x].size() < vstr[y].size();
    } else {
      int id = cl[x][y];
      return tx[vstr[x][id]][vstr[y][id]];
    };
  });
  for (auto x : vec[now]) {
    if (x != k - 1) {
      ans++;
    } else {
      break;
    }
  }
  return ans;
}

int main(int argc, const char *argv[]) {
  memset(hh, -1, sizeof(hh));
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    scanf("%s", s);
    int len = strlen(s);
    insert(s, i);
    vv.push_back(string(s));
    if (len >= B) {
      idx[i] = vstr.size();
      vstr.push_back(string(s));
      key.push_back(vector<ull>());
      key.back().push_back(s[0]);
      for (int j = 1; j < len; j++) {
        key.back().push_back(key.back().back() * base + s[j]);
      }
    }
  }
  for (int i = 0; i < (int)vstr.size(); i++) {
    for (int j = i + 1; j < (int)vstr.size(); j++) {
      const string &x = vstr[i], y = vstr[j];
      int low = 0, high = (int)min(x.size(), y.size()) - 1;
      while (low <= high) {
        int mid = (low + high) / 2;
        if (key[i][mid] != key[j][mid]) {
          high = mid - 1;
        } else {
          low = mid + 1;
        }
      }
      if (low > (int)min(x.size(), y.size()) - 1) {
        cl[i][j] = cl[j][i] = -1;
      } else {
        cl[i][j] = cl[j][i] = low;
      }
    }
  }
  int q;
  cin >> q;
  while (q--) {
    int k;
    string t;
    cin >> k >> t;
    int now = 0;
    cout << solve(k, t) + 1 << endl;
  }
  return 0;
}


Fixed submission:
/*************************************************************************

       Author:            palayutm
       Created Time :     Mon 10 Oct 2016 12:13:01 PM CST

       File Name:         e.cc
       Description:       new style, new life

 ************************************************************************/
#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;

const ull base = 1e9 + 7;

const int B = 640;

int ch[400005][26], cnt = 1;
vector<int> vec[400006];
vector<string> vstr, vv;
vector<vector<ull>> key;
int cl[B + 100][B + 100];
int idx[100005];
bool tx[256][267];
int hh[400005];

void insert(char *s, int id) {
  int now = 0;
  for (int i = 0; s[i]; i++) {
    int c = s[i] - 'a';
    if (!ch[now][c]) {
      ch[now][c] = cnt++;
    }
    now = ch[now][c];
    vec[now].push_back(id);
  }
  hh[now] = id;
}

char s[400005];

int solve(int k, const string &t) {
  string &s = vv[k - 1];
  for (int i = 0; i < 26; i++) {
    for (int j = i + 1; j < 26; j++) {
      tx[t[i]][t[j]] = 1;
      tx[t[j]][t[i]] = 0;
    }
  }
  int ans = 0;
  int now = 0;
  for (int i = 0; i < min(B, (int)s.size()); i++) {
    if (hh[now] >= 0) {
      ans++;
    }
    for (int j = 0; j < 26; j++) {
      if (t[j] == s[i]) {
        now = ch[now][s[i] - 'a'];
        break;
      }
      int c = t[j] - 'a';
      int num = vec[ch[now][c]].size();
      ans += num;
    }
  }
  if (s.size() < B) {
    return ans;
  }
  sort(vec[now].begin(), vec[now].end(), [](const int xx, const int yy) {
    int x = idx[xx], y = idx[yy];
    if (cl[x][y] == -1) {
      return vstr[x].size() < vstr[y].size();
    } else {
      int id = cl[x][y];
      return tx[vstr[x][id]][vstr[y][id]];
    };
  });
  for (auto x : vec[now]) {
    if (x != k - 1) {
      ans++;
    } else {
      break;
    }
  }
  return ans;
}

int main(int argc, const char *argv[]) {
  memset(hh, -1, sizeof(hh));
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    scanf("%s", s);
    int len = strlen(s);
    insert(s, i);
    vv.push_back(string(s));
    if (len >= B) {
      idx[i] = vstr.size();
      vstr.push_back(string(s));
      key.push_back(vector<ull>());
      key.back().push_back(s[0]);
      for (int j = 1; j < len; j++) {
        key.back().push_back(key.back().back() * base + s[j]);
      }
    }
  }
  for (int i = 0; i < (int)vstr.size(); i++) {
    for (int j = i + 1; j < (int)vstr.size(); j++) {
      const string &x = vstr[i], y = vstr[j];
      int low = 0, high = (int)min(x.size(), y.size()) - 1;
      while (low <= high) {
        int mid = (low + high) / 2;
        if (key[i][mid] != key[j][mid]) {
          high = mid - 1;
        } else {
          low = mid + 1;
        }
      }
      if (low > (int)min(x.size(), y.size()) - 1) {
        cl[i][j] = cl[j][i] = -1;
      } else {
        cl[i][j] = cl[j][i] = low;
      }
    }
  }
  int q;
  cin >> q;
  while (q--) {
    int k;
    string t;
    cin >> k >> t;
    int now = 0;
    cout << solve(k, t) + 1 << endl;
  }
  return 0;
}