Problem p02589 (C++) — buggy submission, verdict: Runtime Error

// #include <cstdio>
// #include <string>
// #include <iostream>
// #include <unordered_map>

// using namespace std;
// string s[200000];

// int main(){
//     unordered_map<string, long long> mp;
//     int n, i, l, j;
//     scanf("%d", &n);
//     int m = n;
//     long long ans = 0;
//     while(n--){
//         cin >> s[n];
//         l = s[n].length();
//         int d[26] = {0};
//         for(i = 0; i < 26; ++i)
//             d[i] = -1;
//         for(i = l - 1; i >= 0; --i)
//             d[s[n][i] - 'a'] = i;
//         //ans += mp[s];
//         string str;
//         for(i = 0; i < 26; ++i)
//             if(~d[i]){
//                 str = "a";
//                 str[0] += i;
//                 ++mp[str];
//         }
//         for(i = l - 1; i >= 1; --i){
//             str = s[n].substr(i, l - i);
//             for(j = 0; j < 26; ++j){
//                 if(d[j] < i && ~d[j]){
//                     string pstr = "a";
//                     pstr[0] += j;
//                     pstr.append(str);
//                     ++mp[pstr];
//                 }
//             }
//         }
//     }
//     while(m--)
//         ans += mp[s[m]] - 1;
//     printf("%lld\\n", ans);
//     return 0;
// }

#include <cstdio>
#include <cstring>
#include <set>

struct Trie {
  Trie *children[26];
  int is_end;
  int num[26];

  Trie() {
    for (int i = 0; i < 26; ++i) {
      children[i] = NULL;
      num[i] = 0;
    }
    is_end = 0;
  }
  Trie *upsert(char ch) {
    if (children[ch - 'a'] == NULL)
      children[ch - 'a'] = new Trie();
    return children[ch - 'a'];
  }
  Trie *find(char ch) { return children[ch - 'a']; }
};

int main() {
  int n;
  scanf("%d", &n);
  char s[1000005];
  Trie *root = new Trie();
  Trie *p, *q;
  int len;
  int i, j;
  int d[26];
  int t;
  long long ans = 0;
  while (n--) {
    scanf("%s", s);
    len = strlen(s);
    for (i = 0; i < 26; ++i)
      d[i] = 0x7FFFFFFF;
    // std::set<char> se;
    for (i = len - 1; i >= 0; --i)
      d[s[i] - 'a'] = i;
    for (i = 0; i < 26; ++i)
      if (d[i] < len) {
        ++root->num[i];
        q = root->find('a' + i);
        if (q)
          ans += (long long)q->is_end;
        // printf("%c%d ", 'a' + i, ans);
      }
    p = root;
    // printf("%lld ", ans);
    for (i = len - 1; i >= 1; --i) {
      p = p->upsert(s[i]);
      for (j = 0; j < 26; ++j)
        if (d[j] < i) {
          ++p->num[j];
          q = p->find('a' + j);
          if (q)
            ans += q->is_end;
        }
    }
    ans += (long long)(p->num[s[0] - 'a'] - 1);
    p = p->upsert(s[0]);
    ++p->is_end;
    // printf("%lld ", ans);
    //++p->num;
    // printf("%lld\\n", ans);
  }
  printf("%lld\\n", ans);
  return 0;
}


Error: 0

Fixed submission:

// #include <cstdio>
// #include <string>
// #include <iostream>
// #include <unordered_map>

// using namespace std;
// string s[200000];

// int main(){
//     unordered_map<string, long long> mp;
//     int n, i, l, j;
//     scanf("%d", &n);
//     int m = n;
//     long long ans = 0;
//     while(n--){
//         cin >> s[n];
//         l = s[n].length();
//         int d[26] = {0};
//         for(i = 0; i < 26; ++i)
//             d[i] = -1;
//         for(i = l - 1; i >= 0; --i)
//             d[s[n][i] - 'a'] = i;
//         //ans += mp[s];
//         string str;
//         for(i = 0; i < 26; ++i)
//             if(~d[i]){
//                 str = "a";
//                 str[0] += i;
//                 ++mp[str];
//         }
//         for(i = l - 1; i >= 1; --i){
//             str = s[n].substr(i, l - i);
//             for(j = 0; j < 26; ++j){
//                 if(d[j] < i && ~d[j]){
//                     string pstr = "a";
//                     pstr[0] += j;
//                     pstr.append(str);
//                     ++mp[pstr];
//                 }
//             }
//         }
//     }
//     while(m--)
//         ans += mp[s[m]] - 1;
//     printf("%lld\\n", ans);
//     return 0;
// }

#include <cstdio>
#include <cstring>
#include <set>

struct Trie {
  Trie *children[26];
  int is_end;
  int num;

  Trie() {
    for (int i = 0; i < 26; ++i)
      children[i] = NULL;
    is_end = 0;
    num = 0;
  }
  Trie *upsert(char ch) {
    if (children[ch - 'a'] == NULL)
      children[ch - 'a'] = new Trie();
    return children[ch - 'a'];
  }
};

int main() {
  int n;
  scanf("%d", &n);
  char s[1000005];
  Trie *root = new Trie();
  Trie *p;
  int len;
  int i, j;
  int d[26];
  long long ans = 0;
  while (n--) {
    scanf("%s", s);
    len = strlen(s);
    for (i = 0; i < 26; ++i)
      d[i] = 0;
    std::set<char> se;
    for (i = len - 1; i >= 0; --i) {
      ++d[s[i] - 'a'];
      se.insert(s[i]);
    }
    for (char ch : se) {
      p = root->upsert(ch);
      ++p->num;
      ans += (long long)p->is_end;
    }
    p = root;
    // printf("%lld ", ans);
    for (i = len - 1; i >= 1; --i) {
      p = p->upsert(s[i]);
      --d[s[i] - 'a'];
      if (!d[s[i] - 'a'])
        se.erase(s[i]);
      for (char ch : se) {
        ++p->upsert(ch)->num;
        ans += p->upsert(ch)->is_end;
      }
    }
    p = p->upsert(s[0]);
    ++p->is_end;
    // printf("%lld ", ans);
    ans += (long long)p->num - 1;
    //++p->num;
    // printf("%lld\\n", ans);
  }
  printf("%lld\\n", ans);
  return 0;
}