제출 #591327

#제출 시각아이디문제언어결과실행 시간메모리
591327alextodoranCubeword (CEOI19_cubeword)C++17
100 / 100
227 ms8232 KiB
/**
 ____ ____ ____ ____ ____
||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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...