1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| #include <bits/stdc++.h> using namespace std; using ll = long long;
const int MOD = 888888883; const int STRING_LEN = 50;
string generate_string(int idx) { vector<int> b(STRING_LEN); ll a = 88888888LL; for (int i = 0; i < idx * STRING_LEN; i++) { a = (8888LL * a) % MOD; } for (int i = 0; i < STRING_LEN; i++) { b[i] = a % 3; a = (8888LL * a) % MOD; } string s; for (int i = 0; i < STRING_LEN; i++) { if (b[i] == 0) s += 'x'; else if (b[i] == 1) s += 'y'; else s += 'z'; } return s; }
int calc_inv_parity(const string& s) { int inv = 0; int cnt[3] = {0, 0, 0}; for (char c : s) { int val; if (c == 'x') val = 0; else if (c == 'y') val = 1; else val = 2; for (int i = val + 1; i < 3; i++) { inv ^= (cnt[i] & 1); } cnt[val] ^= 1; } return inv; }
int calc_cross_inv_parity(const array<int, 3>& cnt1, const array<int, 3>& cnt2) { int cross = 0; cross = (cnt1[1] & cnt2[0]) ^ (cnt1[2] & cnt2[0]) ^ (cnt1[2] & cnt2[1]); return cross; }
ll solve(int max_n) { map<tuple<int, int, int, int>, int> feat_count; for (int i = 0; i < max_n; i++) { string s = generate_string(i); array<int, 3> cnt = {0, 0, 0}; for (char c : s) { if (c == 'x') cnt[0]++; else if (c == 'y') cnt[1]++; else cnt[2]++; } int inv = calc_inv_parity(s); auto key = make_tuple(cnt[0] % 2, cnt[1] % 2, cnt[2] % 2, inv); feat_count[key]++; } ll result = 0; for (auto& [feat1, count1] : feat_count) { auto [x1, y1, z1, inv1] = feat1; for (auto& [feat2, count2] : feat_count) { auto [x2, y2, z2, inv2] = feat2; if ((x1 ^ x2) == 1 || (y1 ^ y2) == 1 || (z1 ^ z2) == 1) { continue; } array<int, 3> c1 = {x1, y1, z1}; array<int, 3> c2 = {x2, y2, z2}; int cross = calc_cross_inv_parity(c1, c2); int total_inv = inv1 ^ inv2 ^ cross; if (total_inv == 0) { result += (ll)count1 * count2; } } } return result; }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << "f(10) = " << solve(10) << endl; cout << "f(100) = " << solve(100) << endl; return 0; }
|