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
#include <cstdio>
#include <cstring>
#include <numeric>
#include <algorithm>

bool is_vowel(char c)
{
  constexpr auto vowels = {'a', 'e', 'i', 'o', 'u', 'y'};
  return std::find(vowels.begin(), vowels.end(), c) != vowels.end();
}

constexpr bool is_same(int val1, int val2)
{
  return val1 == val2;
}
template<typename... Args>
constexpr bool is_same(int val1, int val2, Args... args)
{
  return val1 == val2 && is_same(val2, args...);
}

char wishes[200001]; // 0..199999 + \0
char vowelsStorage[200000 + 3]; // 0..199999 + 3 chars buffer
char* vowels = &vowelsStorage[3]; // -3..199999 is valid and initialized
int endingHere[200000]; // 0..199999 = number of difficult words ending at index i

int main()
{
  scanf("%s", wishes);
  const int n = strlen(wishes);

  std::transform(wishes, wishes + n, vowels, [](char c){ return is_vowel(c) ? 'a' : 'b'; });

  for (int i = 2; i < n; i++)
  {
    if (is_same(vowels[i - 3], vowels[i - 2], vowels[i - 1], vowels[i])) // continue group
      endingHere[i] = endingHere[i - 1] + 1;
    else if (is_same(vowels[i - 2], vowels[i - 1], vowels[i])) // start new group
      endingHere[i] = i - 1;
    else // no group
      endingHere[i] = endingHere[i - 1];
  }
  printf("%lld\n", std::accumulate<int*, long long>(endingHere, endingHere + n, 0));
}