#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"; } |