Combothermal

CEOI cubeword

Jul 25th, 2019
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.65 KB | None | 0 0
  1. #pragma GCC optimize ("O3")
  2. #pragma GCC target ("sse4")
  3.  
  4. #include <bits/stdc++.h>
  5. #include <ext/pb_ds/tree_policy.hpp>
  6. #include <ext/pb_ds/assoc_container.hpp>
  7.  
  8. using namespace std;
  9. using namespace __gnu_pbds;
  10.  
  11. typedef long long ll;
  12. typedef long double ld;
  13. typedef complex<ld> cd;
  14.  
  15. typedef pair<int, int> pi;
  16. typedef pair<ll,ll> pl;
  17. typedef pair<ld,ld> pd;
  18.  
  19. typedef vector<int> vi;
  20. typedef vector<ld> vd;
  21. typedef vector<ll> vl;
  22. typedef vector<pi> vpi;
  23. typedef vector<pl> vpl;
  24. typedef vector<cd> vcd;
  25.  
  26. template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;
  27.  
  28. #define FOR(i, a, b) for (int i=a; i<(b); i++)
  29. #define F0R(i, a) for (int i=0; i<(a); i++)
  30. #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
  31. #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
  32.  
  33. #define sz(x) (int)(x).size()
  34. #define mp make_pair
  35. #define pb push_back
  36. #define f first
  37. #define s second
  38. #define lb lower_bound
  39. #define ub upper_bound
  40. #define all(x) x.begin(), x.end()
  41. #define shandom_ruffle random_shuffle
  42.  
  43. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  44.  
  45. const int MOD = 998244353;
  46. const ll INF = 1e18;
  47. const int MX = 100001; //check the limits, dummy
  48.  
  49. vector<string> data;
  50.  
  51. int getMul(int A, int B, int C, int D) {
  52. if (A == B && C == D && B != C) return 6;
  53. if (A == B && B == C && C == D) return 1;
  54. if (A == B && B == C && C != D) return 4;
  55. if (A != B && B == C && C == D) return 4;
  56. if (A != B && B != C && C != D) return 24;
  57. return 12;
  58. }
  59.  
  60. int getMap(char C) {
  61. if (C >= 'a' && C <= 'z') {
  62. return C-'a';
  63. } else if (C >= 'A' && C <= 'Z') {
  64. return 26+C-'A';
  65. } else {
  66. return 52+C-'0';
  67. }
  68. }
  69.  
  70. ll solve(int L) {
  71. int N = sz(data);
  72. ll count[64][64];
  73. F0R(i, 64) {
  74. F0R(j, 64) {
  75. count[i][j] = 0;
  76. }
  77. }
  78.  
  79. F0R(i, N) {
  80. if (sz(data[i]) != L) continue;
  81. int A = getMap(data[i][0]);
  82. int B = getMap(data[i][L-1]);
  83. count[A][B]++;
  84. string S = data[i];
  85. reverse(all(S));
  86. if (S != data[i]) count[B][A]++;
  87. }
  88.  
  89. ll ways[64][64][64];
  90. F0R(i, 64) {
  91. FOR(j, i, 64) {
  92. FOR(k, j, 64) {
  93. ways[i][j][k] = 0;
  94. F0R(l, 64) {
  95. ll cur = 1;
  96. cur *= count[l][i]; cur %= MOD;
  97. cur *= count[l][j]; cur %= MOD;
  98. cur *= count[l][k]; cur %= MOD;
  99. ways[i][j][k] += cur; ways[i][j][k] %= MOD;
  100. }
  101. }
  102. }
  103. }
  104.  
  105. ll ans = 0;
  106.  
  107. F0R(i, 64) {
  108. FOR(j, i, 64) {
  109. FOR(k, j, 64) {
  110. FOR(l, k, 64) {
  111. ll cur = 1;
  112. cur *= ways[i][j][k]; cur %= MOD;
  113. cur *= ways[i][j][l]; cur %= MOD;
  114. cur *= ways[i][k][l]; cur %= MOD;
  115. cur *= ways[j][k][l]; cur %= MOD;
  116. cur *= getMul(i, j, k, l); cur %= MOD;
  117. ans += cur; ans %= MOD;
  118. }
  119. }
  120. }
  121. }
  122. return ans;
  123. }
  124.  
  125.  
  126. int main() {
  127. ios_base::sync_with_stdio(0); cin.tie(0);
  128.  
  129. ll ans = 0;
  130. int N; cin >> N;
  131. set<string> used;
  132. F0R(i, N) {
  133. string S; cin >> S;
  134. if (used.count(S)) continue;
  135. reverse(all(S));
  136. if (used.count(S)) continue;
  137. data.pb(S);
  138. used.insert(S);
  139. }
  140.  
  141. FOR(i, 3, 11) {
  142. ans += solve(i);
  143. ans %= MOD;
  144. }
  145.  
  146. cout << ans << endl;
  147.  
  148. return 0;
  149. }
  150.  
  151. // read the question correctly (ll vs int)
  152. // template by bqi343
Advertisement
Add Comment
Please, Sign In to add comment