#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 */ |
English