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