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
128
129
130
#include <iostream>

using namespace std;

/*
n - długość tekstu

1 <= n < 200000

Teksty krótsze niż 3 znaki, to nie ma ryzyka, trudnych fragmentów jest "0".

Dla dłuższych tekstów możemy oznaczyć sobie każsą trójkę jako ryzykowną 
(cyfra - wartośc tylko dla przejrzystości dalszej analizy) 
lub nie (-), i tak dla przykładowego teksu mam:
  tekst:                  takakostkajakszescian
  spółgłoski/samogłoski:  '.'.'.'''.'.'''.''..'
  ryzykowne trójki:         ------1-----2------

Teraz chcąc ocenić ryzykowne czkórki, badam kolejne dwie ryzykowne trójki 
i jeśli choć jedna z nich była ryzykowna, to czwórka też jest ryzykowna. 
Tak samo dla piątek i kolejnych ciągów.

Przykład:
                      111111111   ryzykowne
  pozycja:  0123456789012345678   ciągi:
  3-ki:     ------1-----2------    2
  4:         -----11----22-----    4
  5:          ----111---222----    6
  .            ---1111--2222---    8
  .             --11111-22222--   10
  .              -111111222222-   12
                  1111112222222   13
                   111112222222   12
                    11112222222   11
                     1112222222   10
                      112222222    9
                       12222222    8
                        2222222    7
                            ...
                              2

Widać, że każda ryzykowna trójka tworzy równoległobok ryzykownych n-tek, 
o wymiarach:
  (odległość odległość od początku + 1) x (odległość do następnej ryzykownej)
Dla ostatniej zamiast odległości do następnej liczymy odległość do końca.

m - liczba wszystkich trójek (m = n - 2)
s - liczba ryzykownych trójek
t - ciąg ryzykownych trójek (prawda lub fałsz - zamiast cyfr), 
    pierwszy element ciągu, to t(0)

na końcu ciągu t dodajemy strażnika t(s) = m


Liczba wszystkich ryzykownych podciągów to:
  sum = SUMA [po i=0..s-1] (t(i) + 1) * (t(i+1) - t(i))

Dla powyższego przykładu mamy:
  s = 2 
  t = 6, 12, 19
  sum = (6 + 1) * (12 - 6) + (12 + 1) * (19 - 12) = 133

max_sum ~= max_n ^ 2 / 2 = (2*10^5)^2 /2 = 2 * 10^10 => long long
*/

bool isVowel(char letter)
{
    if (letter == 'a' 
        || letter == 'e'
        || letter == 'i'
        || letter == 'o'
        || letter == 'u'
        || letter == 'y')
    {
        return true;
    }
    return false;
}

int main() 
{
    string text;
    getline(cin, text);
    long long n = text.size();

    if (n < 3)
    {
        cout << 0 << endl;
        return 0;
    }

    long long m = n - 2;

    string::iterator textIt = text.begin();
    char c;
    bool prev2Vowel = isVowel(*textIt);
    ++textIt;
    bool prev1Vowel = isVowel(*textIt);
    ++textIt;
    bool currVowel;

    long long sum = 0;
    long long lastRiskyTrioIndex = -1;
    long long currTrioIndex = -1;
    for (; textIt != text.end(); ++textIt) 
    {
        ++currTrioIndex;
        currVowel = isVowel(*textIt);

        if ((prev2Vowel && prev1Vowel && currVowel)
            || !(prev2Vowel || prev1Vowel || currVowel))
        {
            if (lastRiskyTrioIndex >= 0)
            {
                sum += (lastRiskyTrioIndex + 1) 
                       * (currTrioIndex - lastRiskyTrioIndex);
            }
            lastRiskyTrioIndex = currTrioIndex;
        }
        prev2Vowel = prev1Vowel;
        prev1Vowel = currVowel;
    }
    if (lastRiskyTrioIndex >= 0)
    {
        sum += (lastRiskyTrioIndex + 1) * (m - lastRiskyTrioIndex);
    }

    cout << sum << endl;
    return 0;
}