#include <bits/stdc++.h> #ifndef ONLINE_JUDGE # pragma GCC diagnostic warning "-Wall" # pragma GCC diagnostic warning "-Wextra" # pragma GCC diagnostic warning "-Wformat=2" # pragma GCC diagnostic warning "-Wnull-dereference" # pragma GCC diagnostic warning "-Wduplicated-branches" # pragma GCC diagnostic warning "-Wduplicated-cond" # pragma GCC diagnostic warning "-Wfloat-equal" # pragma GCC diagnostic warning "-Wshadow" # pragma GCC diagnostic warning "-Wconversion" # pragma GCC diagnostic warning "-Wlogical-op" # pragma GCC diagnostic warning "-Wvector-operation-performance" # pragma GCC diagnostic warning "-Wdisabled-optimization" # pragma GCC diagnostic warning "-Wunsafe-loop-optimizations" # pragma GCC diagnostic warning "-Wdouble-promotion" #endif #pragma GCC target "arch=ivybridge", "tune=ivybridge" #if defined(ONLINE_JUDGE) || !defined(__OPTIMIZE__) # pragma GCC optimize "Ofast", "inline", "unroll-loops", "ipa-pta", "no-rtti", \ "no-exceptions", "nothrow-opt", "strict-enums", "stdarg-opt", "tracer" # pragma GCC target "inline-all-stringops" #endif #define rangeof(c) (c).begin(), (c).end() using namespace std; using uint = unsigned int; using ll = long long; using ull = unsigned long long; using ld = long double; template<class T, size_t N> struct ArrayHash { size_t operator()(array<T, N> const& arr) const { size_t result = 0; for(auto const& elem: arr) { result = result * 2137 + hash<T>()(elem); } return result; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int const letterc = 3; string s; cin >> s; ll result = 0; array<int, letterc> cnt = {0, 0, 0}; vector<unordered_map<array<int, letterc>, int, ArrayHash<int, letterc>>> prev(1u << letterc); for(uint var_mask = 0; var_mask < (1u << letterc); var_mask++) { prev[var_mask][cnt]++; } for(char c: s) { cnt[c - 'a']++; #ifdef DEBUG cout << c << "\n"; cout << "cnt: "; for(int i: cnt) { cout << i << " "; } cout << "\n"; #endif array<int, letterc> sorted; for(int i = 0; i < letterc; i++) { sorted[i] = i; } sort(rangeof(sorted), [&](int a, int b) { return cnt[a] < cnt[b]; }); int sub = 0; for(uint var_mask = 0; var_mask < (1u << letterc); var_mask++) { int min_var = INT_MAX; for(int i = 0; i < letterc; i++) { if(var_mask & (1u << i)) { min_var = min(min_var, cnt[i]); } } auto cpy = cnt; for(int i = 0; i < letterc; i++) { if(var_mask & (1u << i)) { cpy[i] -= min_var; } } sub += prev[var_mask][cpy]; #ifdef DEBUG if(prev[var_mask][cpy]) { cout << "prev[" << var_mask << "]["; for(int i = 0; i < letterc; i++) { cout << cpy[i]; if(i != letterc - 1) { cout << " "; } } cout << "] = " << prev[var_mask][cpy] << endl; } #endif prev[var_mask][cpy]++; } result += sub; #ifdef DEBUG cout << "sub = " << sub << "\n"; cout << endl; #endif } cout << result << "\n"; } /* dla (a,b,c) gdzie a<b<c mamy l. sposobow = prev(a-a+k,b-a+k,c-a+k) + prev(a,a+b-b+k,a+c-b+k) + prev(a,b,b+c-c+k) + 1 a=b<c prev(k,k,c-a+k) + prev(a,a,c) + prev(a,a,a+k) + 1 */
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 125 126 127 | #include <bits/stdc++.h> #ifndef ONLINE_JUDGE # pragma GCC diagnostic warning "-Wall" # pragma GCC diagnostic warning "-Wextra" # pragma GCC diagnostic warning "-Wformat=2" # pragma GCC diagnostic warning "-Wnull-dereference" # pragma GCC diagnostic warning "-Wduplicated-branches" # pragma GCC diagnostic warning "-Wduplicated-cond" # pragma GCC diagnostic warning "-Wfloat-equal" # pragma GCC diagnostic warning "-Wshadow" # pragma GCC diagnostic warning "-Wconversion" # pragma GCC diagnostic warning "-Wlogical-op" # pragma GCC diagnostic warning "-Wvector-operation-performance" # pragma GCC diagnostic warning "-Wdisabled-optimization" # pragma GCC diagnostic warning "-Wunsafe-loop-optimizations" # pragma GCC diagnostic warning "-Wdouble-promotion" #endif #pragma GCC target "arch=ivybridge", "tune=ivybridge" #if defined(ONLINE_JUDGE) || !defined(__OPTIMIZE__) # pragma GCC optimize "Ofast", "inline", "unroll-loops", "ipa-pta", "no-rtti", \ "no-exceptions", "nothrow-opt", "strict-enums", "stdarg-opt", "tracer" # pragma GCC target "inline-all-stringops" #endif #define rangeof(c) (c).begin(), (c).end() using namespace std; using uint = unsigned int; using ll = long long; using ull = unsigned long long; using ld = long double; template<class T, size_t N> struct ArrayHash { size_t operator()(array<T, N> const& arr) const { size_t result = 0; for(auto const& elem: arr) { result = result * 2137 + hash<T>()(elem); } return result; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int const letterc = 3; string s; cin >> s; ll result = 0; array<int, letterc> cnt = {0, 0, 0}; vector<unordered_map<array<int, letterc>, int, ArrayHash<int, letterc>>> prev(1u << letterc); for(uint var_mask = 0; var_mask < (1u << letterc); var_mask++) { prev[var_mask][cnt]++; } for(char c: s) { cnt[c - 'a']++; #ifdef DEBUG cout << c << "\n"; cout << "cnt: "; for(int i: cnt) { cout << i << " "; } cout << "\n"; #endif array<int, letterc> sorted; for(int i = 0; i < letterc; i++) { sorted[i] = i; } sort(rangeof(sorted), [&](int a, int b) { return cnt[a] < cnt[b]; }); int sub = 0; for(uint var_mask = 0; var_mask < (1u << letterc); var_mask++) { int min_var = INT_MAX; for(int i = 0; i < letterc; i++) { if(var_mask & (1u << i)) { min_var = min(min_var, cnt[i]); } } auto cpy = cnt; for(int i = 0; i < letterc; i++) { if(var_mask & (1u << i)) { cpy[i] -= min_var; } } sub += prev[var_mask][cpy]; #ifdef DEBUG if(prev[var_mask][cpy]) { cout << "prev[" << var_mask << "]["; for(int i = 0; i < letterc; i++) { cout << cpy[i]; if(i != letterc - 1) { cout << " "; } } cout << "] = " << prev[var_mask][cpy] << endl; } #endif prev[var_mask][cpy]++; } result += sub; #ifdef DEBUG cout << "sub = " << sub << "\n"; cout << endl; #endif } cout << result << "\n"; } /* dla (a,b,c) gdzie a<b<c mamy l. sposobow = prev(a-a+k,b-a+k,c-a+k) + prev(a,a+b-b+k,a+c-b+k) + prev(a,b,b+c-c+k) + 1 a=b<c prev(k,k,c-a+k) + prev(a,a,c) + prev(a,a,a+k) + 1 */ |