This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/**
____ ____ ____ ____ ____
||a |||t |||o |||d |||o ||
||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|
**/
#include <bits/stdc++.h>
//#pragma GCC optimize ("fast-math,unroll-loops")
//#pragma GCC target ("avx2,tune=native,bmi,bmi2")
using namespace std;
typedef long long ll;
const int ALPHA = 26 + 26 + 10;
const int MOD = 998244353;
int encode (char c) {
return (islower(c) ? (int) (c - 'a') : (isupper(c) ? 26 + (int) (c - 'A') : 26 + 26 + (int) (c - '0')));
}
vector <int> adj[ALPHA];
int edges[ALPHA][ALPHA];
int between[ALPHA][ALPHA][ALPHA];
int solve () {
for (int a = 0; a < ALPHA; a++) {
for (int b = a; b < ALPHA; b++) {
for (int c = b; c < ALPHA; c++) {
between[a][b][c] = 0;
}
}
}
for (int d = 0; d < ALPHA; d++) {
for (int i = 0; i < (int) adj[d].size(); i++) {
int a = adj[d][i];
for (int j = i; j < (int) adj[d].size(); j++) {
int b = adj[d][j];
for (int k = j; k < (int) adj[d].size(); k++) {
int c = adj[d][k];
between[a][b][c] = (between[a][b][c] + (ll) edges[a][d] * edges[b][d] % MOD * edges[c][d]) % MOD;
}
}
}
}
ll answer = 0;
for (int a = 0; a < ALPHA; a++) {
for (int b = a; b < ALPHA; b++) {
for (int c = b; c < ALPHA; c++) {
if (between[a][b][c] > 0) {
for (int d = c; d < ALPHA; d++) {
ll ways = (ll) between[a][b][c] * between[a][b][d] % MOD * between[a][c][d] % MOD * between[b][c][d] % MOD;
if (a == b && b == c && c == d) {
ways *= 1;
} else if ((a == b && b == c) || (b == c && c == d)) {
ways *= 4;
} else if (a == b && c == d) {
ways *= 6;
} else if (a == b || b == c || c == d) {
ways *= 12;
} else {
ways *= 24;
}
answer += ways;
}
}
}
}
}
answer %= MOD;
return answer;
}
int main () {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
string word[n * 2];
for (int i = 0; i < n; i++) {
cin >> word[i];
word[i + n] = word[i];
reverse(word[i + n].begin(), word[i + n].end());
if (word[i + n] < word[i]) {
swap(word[i], word[i + n]);
}
if (word[i].front() != word[i].back()) {
reverse(word[i + n].begin(), word[i + n].end());
}
}
sort(word, word + n * 2);
n = unique(word, word + n * 2) - word;
int answer = 0;
for (int k = 3; k <= 10; k++) {
for (int a = 0; a < ALPHA; a++) {
for (int b = 0; b < ALPHA; b++) {
edges[a][b] = 0;
}
adj[a].clear();
}
for (int i = 0; i < n; i++) {
if ((int) word[i].size() == k) {
int a = encode(word[i].front());
int b = encode(word[i].back());
edges[a][b]++;
if (a != b) {
edges[b][a]++;
}
}
}
for (int a = 0; a < ALPHA; a++) {
for (int b = 0; b <= ALPHA; b++) {
if (edges[a][b] > 0) {
adj[a].push_back(b);
}
}
}
answer += solve();
if (answer >= MOD) {
answer -= MOD;
}
}
cout << answer << "\n";
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |