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

// Original Code:
// #include <self/utility>
// #include <self/debug>
// using namespace std;
// int n;
// string s[200005];
// pair<int,int> trie[1000005][27];
// pair<int,int> par[1000005];
// int have[1000005][26];
// int lastch[200005];
// bool used[26];
// int cnt;
//
// void dfs(int x)
//{
//	for(int i=0;i<26;i++)
//	{
//		if(trie[x][i].first)
//		{
//			have[x][i]=trie[x][i].second;
//			dfs(trie[x][i].first);
//			for(int j=0;j<26;j++)
//			{
//				have[x][j]+=have[trie[x][i].first][j];
//			}
//		}
//	}
// }
//
// int main()
//{
////	freopen("input.txt","r",stdin);
//	quickcin;
//	cin>>n;
//	cnt=1;
//	for(int i=0;i<n;i++)
//	{
//		cin>>s[i];
//		reverse(all(s[i]));
//		int now=0;
//		int lastch;
//		for(auto c:s[i])
//		{
//			if(trie[now][c-'a'].first!=0)
//			{
//				trie[now][c-'a'].second++;
//				now=trie[now][c-'a'].first;
//			}
//			else
//			{
//				trie[now][c-'a']=mp(cnt,1);
//				par[cnt]=mp(now,c-'a');
//				now=cnt++;
//			}
//			lastch=now;
//		}
//		::lastch[i]=lastch;
//		trie[lastch][26].second++;
//	}
//	for(int i=0;i<n;i++)
//	{
//		memset(used,0,sizeof(used));
//		int now=lastch[i];
//		while(now)
//		{
//			int pre=par[now].first;
//			int ch=par[now].second;
//			if(!used[ch])
//			{
//				used[ch]=true;
////				have[pre][ch]++;
//			}
//			for(int j=0;j<26;j++)
//			{
//				have[pre][j]+=used[j];
//			}
//			now=pre;
//		}
//	}
////	cout<<have[2][2]<<endl;
////	dfs(0);
//	ll res=0;
//	for(int i=1;i<cnt;i++)
//	{
////		cout<<i<<' '<<trie[i][26].second<<' '<<par[i].first<<'
///'<<par[i].second<<' '<<have[par[i].first][par[i].second]-1<<endl;
//		res+=1LL*trie[i][26].second*(have[par[i].first][par[i].second]-1);
//	}
//	cout<<res<<endl;
//	return 0;
//}

// substituted with C++ Inliner
#ifndef _SELF_UTILITY
#define _SELF_UTILITY 1
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#define Endl endl
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define over(A)                                                                \\
  {                                                                            \\
    cout << A << endl;                                                         \\
    exit(0);                                                                   \\
  }
#define all(A) A.begin(), A.end()
#define ceil(a, b) ((a - 1) / b + 1)
#define quickcin ios_base::sync_with_stdio(false);
const int mod = 1e9 + 7;
const int inf = 1039074182;
const ll llinf = 1LL * inf * inf;
template <typename T1, typename T2> inline void chmin(T1 &x, T2 b) {
  if (b < x)
    x = b;
}
template <typename T1, typename T2> inline void chmax(T1 &x, T2 b) {
  if (b > x)
    x = b;
}
template <typename T1, typename T2> inline void chadd(T1 &x, T2 b) {
  x += b;
  if (x >= mod)
    x -= mod;
}
template <typename T1, typename T2> inline void chmul(T1 &x, T2 b) {
  x = 1LL * x * b % mod;
}
template <typename T1, typename T2> inline void chmod(T1 &x, T2 b) {
  x %= b, x += b;
  if (x >= b)
    x -= b;
}
#endif

#ifndef _SELF_DEBUG
#define _SELF_DEBUG 1
#ifndef _SELF_OPERATOR
#define _SELF_OPERATOR 1
#ifndef _SELF_UTILITY
#define _SELF_UTILITY 1
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#define Endl endl
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define over(A)                                                                \\
  {                                                                            \\
    cout << A << endl;                                                         \\
    exit(0);                                                                   \\
  }
#define all(A) A.begin(), A.end()
#define ceil(a, b) ((a - 1) / b + 1)
#define quickcin ios_base::sync_with_stdio(false);
const int mod = 1e9 + 7;
const int inf = 1039074182;
const ll llinf = 1LL * inf * inf;
template <typename T1, typename T2> inline void chmin(T1 &x, T2 b) {
  if (b < x)
    x = b;
}
template <typename T1, typename T2> inline void chmax(T1 &x, T2 b) {
  if (b > x)
    x = b;
}
template <typename T1, typename T2> inline void chadd(T1 &x, T2 b) {
  x += b;
  if (x >= mod)
    x -= mod;
}
template <typename T1, typename T2> inline void chmul(T1 &x, T2 b) {
  x = 1LL * x * b % mod;
}
template <typename T1, typename T2> inline void chmod(T1 &x, T2 b) {
  x %= b, x += b;
  if (x >= b)
    x -= b;
}
#endif

using namespace std;
template <typename T> ostream &operator<<(ostream &cout, vector<T> vec) {
  cout << "{";
  for (int i = 0; i < vec.size(); i++) {
    cout << vec[i];
    if (i != (int)vec.size() - 1)
      cout << ',';
  }
  cout << "}";
  return cout;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &cout, pair<T1, T2> p) {
  cout << "(" << p.first << ',' << p.second << ")";
  return cout;
}

template <typename T> ostream &operator<<(ostream &cout, set<T> s) {
  vector<T> t;
  for (auto x : s)
    t.push_back(x);
  cout << t;
  return cout;
}

template <typename T> ostream &operator<<(ostream &cout, queue<T> q) {
  vector<T> t;
  while (q.size()) {
    t.push_back(q.front());
    q.pop();
  }
  cout << t;
  return cout;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &cout, map<T1, T2> m) {
  for (auto &x : m) {
    cout << "Key: " << x.first << ' ' << "Value: " << x.second << endl;
  }
  return cout;
}

template <typename T> T operator*(vector<T> v1, vector<T> v2) {
  assert(v1.size() == v2.size());
  int n = v1.size();
  T res = 0;
  for (int i = 0; i < n; i++) {
    res += v1[i] * v2[i];
  }
  return res;
}

template <typename T1, typename T2>
pair<T1, T2> operator+(pair<T1, T2> x, pair<T1, T2> y) {
  return make_pair(x.first + y.first, x.second + y.second);
}

template <typename T1, typename T2> pair<T1, T2> operator-(pair<T1, T2> x) {
  return make_pair(-x.first, -x.second);
}

template <typename T> vector<vector<T>> operator~(vector<vector<T>> vec) {
  vector<vector<T>> v;
  int n = vec.size(), m = vec[0].size();
  v.resize(m);
  for (int i = 0; i < m; i++) {
    v[i].resize(n);
  }
  for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
      v[i][j] = vec[j][i];
    }
  }
  return v;
}
#endif

void print0x(int x) {
  std::vector<int> vec;
  while (x) {
    vec.push_back(x & 1);
    x >>= 1;
  }
  std::reverse(vec.begin(), vec.end());
  for (int i = 0; i < vec.size(); i++) {
    std::cout << vec[i];
  }
  std::cout << ' ';
}

template <typename T> void print0x(T x, int len) {
  std::vector<int> vec;
  while (x) {
    vec.push_back(x & 1);
    x >>= 1;
  }
  reverse(vec.begin(), vec.end());
  for (int i = vec.size(); i < len; i++) {
    putchar('0');
  }
  for (int i = 0; i < vec.size(); i++) {
    std::cout << vec[i];
  }
  std::cout << ' ';
}
#endif
using namespace std;
int n;
string s[200005];
pair<int, int> trie[1000005][27];
pair<int, int> par[1000005];
int have[1000005][26];
int lastch[200005];
bool used[26];
int cnt;

void dfs(int x) {
  for (int i = 0; i < 26; i++) {
    if (trie[x][i].first) {
      have[x][i] = trie[x][i].second;
      dfs(trie[x][i].first);
      for (int j = 0; j < 26; j++) {
        have[x][j] += have[trie[x][i].first][j];
      }
    }
  }
}

int main() {
  //	freopen("input.txt","r",stdin);
  quickcin;
  cin >> n;
  cnt = 1;
  for (int i = 0; i < n; i++) {
    cin >> s[i];
    reverse(all(s[i]));
    int now = 0;
    int lastch;
    for (auto c : s[i]) {
      if (trie[now][c - 'a'].first != 0) {
        trie[now][c - 'a'].second++;
        now = trie[now][c - 'a'].first;
      } else {
        trie[now][c - 'a'] = mp(cnt, 1);
        par[cnt] = mp(now, c - 'a');
        now = cnt++;
      }
      lastch = now;
    }
    ::lastch[i] = lastch;
    trie[lastch][26].second++;
  }
  for (int i = 0; i < n; i++) {
    memset(used, 0, sizeof(used));
    int now = lastch[i];
    while (now) {
      int pre = par[now].first;
      int ch = par[now].second;
      if (!used[ch]) {
        used[ch] = true;
        //				have[pre][ch]++;
      }
      for (int j = 0; j < 26; j++) {
        have[pre][j] += used[j];
      }
      now = pre;
    }
  }
  //	cout<<have[2][2]<<endl;
  //	dfs(0);
  ll res = 0;
  for (int i = 1; i < cnt; i++) {
    //		cout<<i<<' '<<trie[i][26].second<<' '<<par[i].first<<'
    //'<<par[i].second<<' '<<have[par[i].first][par[i].second]-1<<endl;
    res += 1LL * trie[i][26].second * (have[par[i].first][par[i].second] - 1);
  }
  cout << res << endl;
  return 0;
}


Error: 0

Fixed submission:

// Original Code:
// #include <self/utility>
// #include <self/debug>
// using namespace std;
// int n;
// string s[200005];
// pair<int,int> trie[200005][27];
// pair<int,int> par[2000005];
// int have[200005][26];
// int lastch[200005];
// bool used[26];
// int cnt;
//
// void dfs(int x)
//{
//	for(int i=0;i<26;i++)
//	{
//		if(trie[x][i].first)
//		{
//			have[x][i]=trie[x][i].second;
//			dfs(trie[x][i].first);
//			for(int j=0;j<26;j++)
//			{
//				have[x][j]+=have[trie[x][i].first][j];
//			}
//		}
//	}
// }
//
// int main()
//{
////	freopen("input.txt","r",stdin);
//	quickcin;
//	cin>>n;
//	cnt=1;
//	for(int i=0;i<n;i++)
//	{
//		cin>>s[i];
//		reverse(all(s[i]));
//		int now=0;
//		int lastch;
//		for(auto c:s[i])
//		{
//			if(trie[now][c-'a'].first!=0)
//			{
//				trie[now][c-'a'].second++;
//				now=trie[now][c-'a'].first;
//			}
//			else
//			{
//				trie[now][c-'a']=mp(cnt,1);
//				par[cnt]=mp(now,c-'a');
//				now=cnt++;
//			}
//			lastch=now;
//		}
//		::lastch[i]=lastch;
//		trie[lastch][26].second++;
//	}
//	for(int i=0;i<n;i++)
//	{
//		memset(used,0,sizeof(used));
//		int now=lastch[i];
//		while(now)
//		{
//			int pre=par[now].first;
//			int ch=par[now].second;
//			if(!used[ch])
//			{
//				used[ch]=true;
////				have[pre][ch]++;
//			}
//			for(int j=0;j<26;j++)
//			{
//				have[pre][j]+=used[j];
//			}
//			now=pre;
//		}
//	}
////	cout<<have[2][2]<<endl;
////	dfs(0);
//	ll res=0;
//	for(int i=1;i<cnt;i++)
//	{
////		cout<<i<<' '<<trie[i][26].second<<' '<<par[i].first<<'
///'<<par[i].second<<' '<<have[par[i].first][par[i].second]-1<<endl;
//		res+=1LL*trie[i][26].second*(have[par[i].first][par[i].second]-1);
//	}
//	cout<<res<<endl;
//	return 0;
//}

// substituted with C++ Inliner
#ifndef _SELF_UTILITY
#define _SELF_UTILITY 1
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#define Endl endl
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define over(A)                                                                \\
  {                                                                            \\
    cout << A << endl;                                                         \\
    exit(0);                                                                   \\
  }
#define all(A) A.begin(), A.end()
#define ceil(a, b) ((a - 1) / b + 1)
#define quickcin ios_base::sync_with_stdio(false);
const int mod = 1e9 + 7;
const int inf = 1039074182;
const ll llinf = 1LL * inf * inf;
template <typename T1, typename T2> inline void chmin(T1 &x, T2 b) {
  if (b < x)
    x = b;
}
template <typename T1, typename T2> inline void chmax(T1 &x, T2 b) {
  if (b > x)
    x = b;
}
template <typename T1, typename T2> inline void chadd(T1 &x, T2 b) {
  x += b;
  if (x >= mod)
    x -= mod;
}
template <typename T1, typename T2> inline void chmul(T1 &x, T2 b) {
  x = 1LL * x * b % mod;
}
template <typename T1, typename T2> inline void chmod(T1 &x, T2 b) {
  x %= b, x += b;
  if (x >= b)
    x -= b;
}
#endif

#ifndef _SELF_DEBUG
#define _SELF_DEBUG 1
#ifndef _SELF_OPERATOR
#define _SELF_OPERATOR 1
#ifndef _SELF_UTILITY
#define _SELF_UTILITY 1
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#define Endl endl
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define over(A)                                                                \\
  {                                                                            \\
    cout << A << endl;                                                         \\
    exit(0);                                                                   \\
  }
#define all(A) A.begin(), A.end()
#define ceil(a, b) ((a - 1) / b + 1)
#define quickcin ios_base::sync_with_stdio(false);
const int mod = 1e9 + 7;
const int inf = 1039074182;
const ll llinf = 1LL * inf * inf;
template <typename T1, typename T2> inline void chmin(T1 &x, T2 b) {
  if (b < x)
    x = b;
}
template <typename T1, typename T2> inline void chmax(T1 &x, T2 b) {
  if (b > x)
    x = b;
}
template <typename T1, typename T2> inline void chadd(T1 &x, T2 b) {
  x += b;
  if (x >= mod)
    x -= mod;
}
template <typename T1, typename T2> inline void chmul(T1 &x, T2 b) {
  x = 1LL * x * b % mod;
}
template <typename T1, typename T2> inline void chmod(T1 &x, T2 b) {
  x %= b, x += b;
  if (x >= b)
    x -= b;
}
#endif

using namespace std;
template <typename T> ostream &operator<<(ostream &cout, vector<T> vec) {
  cout << "{";
  for (int i = 0; i < vec.size(); i++) {
    cout << vec[i];
    if (i != (int)vec.size() - 1)
      cout << ',';
  }
  cout << "}";
  return cout;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &cout, pair<T1, T2> p) {
  cout << "(" << p.first << ',' << p.second << ")";
  return cout;
}

template <typename T> ostream &operator<<(ostream &cout, set<T> s) {
  vector<T> t;
  for (auto x : s)
    t.push_back(x);
  cout << t;
  return cout;
}

template <typename T> ostream &operator<<(ostream &cout, queue<T> q) {
  vector<T> t;
  while (q.size()) {
    t.push_back(q.front());
    q.pop();
  }
  cout << t;
  return cout;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &cout, map<T1, T2> m) {
  for (auto &x : m) {
    cout << "Key: " << x.first << ' ' << "Value: " << x.second << endl;
  }
  return cout;
}

template <typename T> T operator*(vector<T> v1, vector<T> v2) {
  assert(v1.size() == v2.size());
  int n = v1.size();
  T res = 0;
  for (int i = 0; i < n; i++) {
    res += v1[i] * v2[i];
  }
  return res;
}

template <typename T1, typename T2>
pair<T1, T2> operator+(pair<T1, T2> x, pair<T1, T2> y) {
  return make_pair(x.first + y.first, x.second + y.second);
}

template <typename T1, typename T2> pair<T1, T2> operator-(pair<T1, T2> x) {
  return make_pair(-x.first, -x.second);
}

template <typename T> vector<vector<T>> operator~(vector<vector<T>> vec) {
  vector<vector<T>> v;
  int n = vec.size(), m = vec[0].size();
  v.resize(m);
  for (int i = 0; i < m; i++) {
    v[i].resize(n);
  }
  for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
      v[i][j] = vec[j][i];
    }
  }
  return v;
}
#endif

void print0x(int x) {
  std::vector<int> vec;
  while (x) {
    vec.push_back(x & 1);
    x >>= 1;
  }
  std::reverse(vec.begin(), vec.end());
  for (int i = 0; i < vec.size(); i++) {
    std::cout << vec[i];
  }
  std::cout << ' ';
}

template <typename T> void print0x(T x, int len) {
  std::vector<int> vec;
  while (x) {
    vec.push_back(x & 1);
    x >>= 1;
  }
  reverse(vec.begin(), vec.end());
  for (int i = vec.size(); i < len; i++) {
    putchar('0');
  }
  for (int i = 0; i < vec.size(); i++) {
    std::cout << vec[i];
  }
  std::cout << ' ';
}
#endif
using namespace std;
int n;
string s[200005];
pair<int, int> trie[200005][27];
pair<int, int> par[2000005];
int have[200005][26];
int lastch[200005];
bool used[26];
int cnt;

void dfs(int x) {
  for (int i = 0; i < 26; i++) {
    if (trie[x][i].first) {
      have[x][i] = trie[x][i].second;
      dfs(trie[x][i].first);
      for (int j = 0; j < 26; j++) {
        have[x][j] += have[trie[x][i].first][j];
      }
    }
  }
}

int main() {
  //	freopen("input.txt","r",stdin);
  quickcin;
  cin >> n;
  cnt = 1;
  for (int i = 0; i < n; i++) {
    cin >> s[i];
    reverse(all(s[i]));
    int now = 0;
    int lastch;
    for (auto c : s[i]) {
      if (trie[now][c - 'a'].first != 0) {
        trie[now][c - 'a'].second++;
        now = trie[now][c - 'a'].first;
      } else {
        trie[now][c - 'a'] = mp(cnt, 1);
        par[cnt] = mp(now, c - 'a');
        now = cnt++;
      }
      lastch = now;
    }
    ::lastch[i] = lastch;
    trie[lastch][26].second++;
  }
  for (int i = 0; i < n; i++) {
    memset(used, 0, sizeof(used));
    int now = lastch[i];
    while (now) {
      int pre = par[now].first;
      int ch = par[now].second;
      if (!used[ch]) {
        used[ch] = true;
        //				have[pre][ch]++;
      }
      for (int j = 0; j < 26; j++) {
        have[pre][j] += used[j];
      }
      now = pre;
    }
  }
  //	cout<<have[2][2]<<endl;
  //	dfs(0);
  ll res = 0;
  for (int i = 1; i < cnt; i++) {
    //		cout<<i<<' '<<trie[i][26].second<<' '<<par[i].first<<'
    //'<<par[i].second<<' '<<have[par[i].first][par[i].second]-1<<endl;
    res += 1LL * trie[i][26].second * (have[par[i].first][par[i].second] - 1);
  }
  cout << res << endl;
  return 0;
}