#include <iostream>
#include <unordered_map>
long long one(const std::string &in) {
long long out = 0;
long long run;
char curr = '\0';
for (char c: in) {
if (c == curr) {
run += 1;
} else {
curr = c;
run = 1;
}
out += run;
}
return out;
}
long long two(const std::string &in) {
long long out = 0;
std::unordered_map<int, long long> seen;
std::unordered_map<int, int> which_it;
int it = 0;
for (char a: { 'a', 'b' }) {
for (char b: { 'b', 'c' }) {
if (b <= a) { continue; }
int run = 0;
seen[0] = 1;
it += 1;
which_it[0] = it;
for (char c: in) {
if (c == a) {
run += 1;
} else if (c == b) {
run -= 1;
} else {
it += 1;
run = 0;
}
if (which_it.count(run) == 1 && which_it[run] == it) {
out += seen[run];
seen[run] += 1;
} else {
which_it[run] = it;
seen[run] = 1;
}
}
}
}
return out;
}
struct dat {
int a = 0;
int b = 0;
int c = 0;
void add(char v) {
int &to0 = v == 'a' ? a : v == 'b' ? b : c;
int &to1 = v == 'a' ? b : v == 'b' ? c : a;
int &to2 = v == 'a' ? c : v == 'b' ? a : b;
if (to0 == 0 && to1 > 0 && to2 > 0) {
to1 -= 1;
to2 -= 1;
} else {
to0 += 1;
}
}
bool operator==(const dat &other) const {
return a == other.a && b == other.b && c == other.c;
}
};
template<>
struct std::hash<dat>
{
std::size_t operator()(const dat &d) const
{
std::size_t ha = std::hash<int>{}(d.a);
std::size_t hb = std::hash<int>{}(d.b);
std::size_t hc = std::hash<int>{}(d.c);
return ha ^ (hb << 1) ^ (hc >> 1);
}
};
long long three(const std::string &in) {
long long out = 0;
std::unordered_map<dat, long long> seen;
dat run;
seen[run] = 1;
for (char c: in) {
run.add(c);
out += seen[run];
seen[run] += 1;
}
return out;
}
int main() {
std::string in;
std::cin >> in;
std::cout << one(in) + two(in) + three(in) << "\n";
}
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 | #include <iostream> #include <unordered_map> long long one(const std::string &in) { long long out = 0; long long run; char curr = '\0'; for (char c: in) { if (c == curr) { run += 1; } else { curr = c; run = 1; } out += run; } return out; } long long two(const std::string &in) { long long out = 0; std::unordered_map<int, long long> seen; std::unordered_map<int, int> which_it; int it = 0; for (char a: { 'a', 'b' }) { for (char b: { 'b', 'c' }) { if (b <= a) { continue; } int run = 0; seen[0] = 1; it += 1; which_it[0] = it; for (char c: in) { if (c == a) { run += 1; } else if (c == b) { run -= 1; } else { it += 1; run = 0; } if (which_it.count(run) == 1 && which_it[run] == it) { out += seen[run]; seen[run] += 1; } else { which_it[run] = it; seen[run] = 1; } } } } return out; } struct dat { int a = 0; int b = 0; int c = 0; void add(char v) { int &to0 = v == 'a' ? a : v == 'b' ? b : c; int &to1 = v == 'a' ? b : v == 'b' ? c : a; int &to2 = v == 'a' ? c : v == 'b' ? a : b; if (to0 == 0 && to1 > 0 && to2 > 0) { to1 -= 1; to2 -= 1; } else { to0 += 1; } } bool operator==(const dat &other) const { return a == other.a && b == other.b && c == other.c; } }; template<> struct std::hash<dat> { std::size_t operator()(const dat &d) const { std::size_t ha = std::hash<int>{}(d.a); std::size_t hb = std::hash<int>{}(d.b); std::size_t hc = std::hash<int>{}(d.c); return ha ^ (hb << 1) ^ (hc >> 1); } }; long long three(const std::string &in) { long long out = 0; std::unordered_map<dat, long long> seen; dat run; seen[run] = 1; for (char c: in) { run.add(c); out += seen[run]; seen[run] += 1; } return out; } int main() { std::string in; std::cin >> in; std::cout << one(in) + two(in) + three(in) << "\n"; } |
English