Day5T1
考虑枚举立方体的4个顶点分别填什么,预处理出每个顶点影响的其它三个顶点共有多少种填法。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 998244353;
const int N = 1e5+5;
const int C = 70;
ll cnt[C][C],cnt2[C][C],dp[C][C][C];
unordered_set<string> st[C][C];
string s[N];
int to_num(char c){
if('a'<=c&&c<='z') return c-'a'+1;
if('A'<=c&&c<='Z') return c-'A'+27;
if('0'<=c&&c<='9') return (c^0x30)+53;
}
string d(const string& str){
string ans(str.size(),'0');
for(int i=0;i<str.size();i++) ans[str.size()-1-i] = str[i];
return ans;
}
int main(){
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>s[i];
sort(s+1,s+n+1,[](const string& a,const string& b)->bool{
return a.size()<b.size();
});
ll ans = 0;
for(int i=1;i<=n;){
int siz = s[i].size(),mx = 0;
for(;s[i].size()==siz;i++){
int a = to_num(s[i][0]),b = to_num(s[i].back());
st[a][b].insert(s[i]);
st[b][a].insert(d(s[i]));
mx = max(mx,max(a,b));
}
for(int i=1;i<=mx;i++) for(int j=1;j<=mx;j++) cnt[i][j] = st[i][j].size();
for(int j=1;j<=mx;j++) for(int l=1;l<=mx;l++) for(int k=1;k<=mx;k++){
dp[j][l][k] = 0;
for(int s=1;s<=mx;s++) dp[j][l][k] = (dp[j][l][k]+cnt[j][s]*cnt[l][s]%MOD*cnt[k][s])%MOD;
}
for(int j=1;j<=mx;j++) for(int l=1;l<=mx;l++) for(int k=1;k<=mx;k++) for(int s=1;s<=mx;s++){
ans = (ans+dp[j][l][k]*dp[l][k][s]%MOD*dp[k][s][j]%MOD*dp[s][j][l])%MOD;
}
for(int j=1;j<=mx;j++) for(int l=1;l<=mx;l++) st[j][l].clear();
}
cout<<ans;
return 0;
}

浙公网安备 33010602011771号