Submission #518662

#TimeUsernameProblemLanguageResultExecution timeMemory
518662MonarchuwuCubeword (CEOI19_cubeword)C++17
50 / 100
1172 ms49136 KiB
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<unordered_set>
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;

const int N = 1e5 + 9, mod = 998244353;
int n;
int a[11][62][62][2];

bool palind(string s) {
    int l(0), r(s.size() - 1);
    while (l < r) {
        if (s[l] != s[r]) return false;
        ++l, --r;
    }
    return true;
}

int num(char c) {
    if ('a' <= c && c <= 'z') return c - 'a';
    if ('A' <= c && c <= 'Z') return c - 'A' + 26;
    if ('0' <= c && c <= '9') return c - '0' + 52;
    return -1;
}

ll calc(int len, int i, int j) {
    if (i != j) {
        if (i > j) swap(i, j);
        return a[len][i][j][0];
    }
    return (a[len][i][j][1] + a[len][i][j][0] * 2) % mod;
}

ll dp[2][62][62][62][62];
void reset() {
    for (int i1 = 0; i1 < n; ++i1)
        for (int i2 = 0; i2 < n; ++i2)
            for (int i3 = 0; i3 < n; ++i3)
                for (int i4 = 0; i4 < n; ++i4) {
                    dp[0][i1][i2][i3][i4] = dp[1][i1][i2][i3][i4];
                    dp[1][i1][i2][i3][i4] = 0;
                }
}

int main() {
    cin.tie(NULL)->sync_with_stdio(false);
    cin >> n;

    unordered_set<string> S;
    vector<int> ch;
    for (int ii = 0; ii < n; ++ii) {
        string s; cin >> s;
        if (S.count(s)) continue;

        int i = num(s[0]), j = num(s.back());
        if (i > j) swap(i, j);
        ch.push_back(i);
        ch.push_back(j);

        ++a[s.size()][i][j][palind(s)];
        reverse(all(s));
        S.insert(s);
    }
    sort(all(ch));
    ch.resize(unique(all(ch)) - ch.begin());
    n = ch.size();

    for (int len = 3; len <= 10; ++len)
        for (int i = 0; i < n; ++i)
            for (int j = i; j < n; ++j) {
                int i1 = ch[i], i2 = ch[j];
                a[len][i][j][0] = a[len][i1][i2][0];
                a[len][i][j][1] = a[len][i1][i2][1];
            }

    ll ans(0);
    for (int len = 3; len <= 10; ++len) {
        for (int i1 = 0; i1 < n; ++i1)
            for (int i2 = 0; i2 < n; ++i2)
                for (int i3 = 0; i3 < n; ++i3)
                    for (int i4 = 0; i4 < n; ++i4)
                        dp[1][i1][i2][i3][i4] = calc(len, i1, i2) * calc(len, i2, i3) % mod * calc(len, i3, i4) % mod * calc(len, i4, i1) % mod;
        reset();

        for (int i5 = 0; i5 < n; ++i5)
            for (int i1 = 0; i1 < n; ++i1)
                for (int i2 = 0; i2 < n; ++i2)
                    for (int i3 = 0; i3 < n; ++i3)
                        for (int i4 = 0; i4 < n; ++i4) if (dp[0][i1][i2][i3][i4])
                            (dp[1][i5][i2][i3][i4] += dp[0][i1][i2][i3][i4] * calc(len, i1, i5)) %= mod;
        reset();

        for (int i6 = 0; i6 < n; ++i6)
            for (int i5 = 0; i5 < n; ++i5)
                for (int i2 = 0; i2 < n; ++i2)
                    for (int i3 = 0; i3 < n; ++i3)
                        for (int i4 = 0; i4 < n; ++i4)
                            (dp[1][i5][i6][i3][i4] += dp[0][i5][i2][i3][i4] * calc(len, i2, i6) % mod * calc(len, i5, i6)) %= mod;
        reset();

        for (int i7 = 0; i7 < n; ++i7)
            for (int i5 = 0; i5 < n; ++i5)
                for (int i6 = 0; i6 < n; ++i6)
                    for (int i3 = 0; i3 < n; ++i3)
                        for (int i4 = 0; i4 < n; ++i4) if (dp[0][i5][i6][i3][i4])
                            (dp[1][i5][i6][i7][i4] += dp[0][i5][i6][i3][i4] * calc(len, i3, i7) % mod * calc(len, i6, i7)) %= mod;
        reset();

        for (int i8 = 0; i8 < n; ++i8)
            for (int i5 = 0; i5 < n; ++i5)
                for (int i6 = 0; i6 < n; ++i6)
                    for (int i7 = 0; i7 < n; ++i7)
                        for (int i4 = 0; i4 < n; ++i4)
                            (dp[1][i5][i6][i7][i8] += dp[0][i5][i6][i7][i4] * calc(len, i4, i8) % mod * calc(len, i7, i8) % mod * calc(len, i8, i5)) %= mod;
        reset();

        for (int i5 = 0; i5 < n; ++i5)
            for (int i6 = 0; i6 < n; ++i6)
                for (int i7 = 0; i7 < n; ++i7)
                    for (int i8 = 0; i8 < n; ++i8)
                        (ans += dp[0][i5][i6][i7][i8]) %= mod;
    }
    cout << ans << '\n';
}
/**  /\_/\
 *  (= ._.)
 *  / >0  \>1
**/
/*
    for (int len = 3; len <= 10; ++len)
        for (int i1 = 0; i1 < n; ++i1)
            for (int i2 = 0; i2 < n; ++i2)
                for (int i3 = 0; i3 < n; ++i3)
                    for (int i4 = 0; i4 < n; ++i4)
                        for (int i5 = 0; i5 < n; ++i5)
                            for (int i6 = 0; i6 < n; ++i6)
                                for (int i7 = 0; i7 < n; ++i7)
                                    for (int i8 = 0; i8 < n; ++i8) {
                                        ans += calc(len, i1, i2) * calc(len, i2, i3) % mod * calc(len, i3, i4) % mod * calc(len, i4, i1) % mod
                                            * calc(len, i1, i5) % mod * calc(len, i2, i6) % mod * calc(len, i3, i7) % mod * calc(len, i4, i8) % mod
                                            * calc(len, i5, i6) % mod * calc(len, i6, i7) % mod * calc(len, i7, i8) % mod * calc(len, i8, i5);
                                        ans %= mod;
                                    }
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...