<p>Given the string <code>s</code>, return the size of the longest substring containing each vowel an even number of times. That is, &#39;a&#39;, &#39;e&#39;, &#39;i&#39;, &#39;o&#39;, and &#39;u&#39; must appear an even number of times.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;eleetminicoworoep&quot;
<strong>Output:</strong> 13
<strong>Explanation: </strong>The longest substring is &quot;leetminicowor&quot; which contains two each of the vowels: <strong>e</strong>, <strong>i</strong> and <strong>o</strong> and zero of the vowels: <strong>a</strong> and <strong>u</strong>.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;leetcodeisgreat&quot;
<strong>Output:</strong> 5
<strong>Explanation:</strong> The longest substring is &quot;leetc&quot; which contains two e&#39;s.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;bcbcbc&quot;
<strong>Output:</strong> 6
<strong>Explanation:</strong> In this case, the given string &quot;bcbcbc&quot; is the longest because all vowels: <strong>a</strong>, <strong>e</strong>, <strong>i</strong>, <strong>o</strong> and <strong>u</strong> appear zero times.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= s.length &lt;= 5 x 10^5</code></li>
	<li><code>s</code>&nbsp;contains only lowercase English letters.</li>
</ul>


namespace
{
    template <typename Tbitset>
    struct char_bitset_t : Tbitset
    {
        template <typename... Tchars>
        constexpr char_bitset_t(Tchars ... tChars)
        {
            for (char const cCHAR : {tChars...})
            {
                (*this)[cCHAR] = true;
            }
        }
    };
    constexpr static char_bitset_t<std::bitset<128>> g_bitsetVOWEL('a', 'e', 'i', 'o', 'u');

    constexpr static bool is_vowel(char const c)
    {
        return g_bitsetVOWEL[c];
    }
    static_assert(is_vowel('a'));
    static_assert(is_vowel('e'));
    static_assert(is_vowel('i'));
    static_assert(is_vowel('o'));
    static_assert(is_vowel('u'));
    static_assert(is_vowel('b') == false);
}

class Solution
{
public:
    static_assert(('a' ^ 'e' ^ 'i' ^ 'o' ^ 'u'));
    static_assert(('a' ^ 'e' ^ 'i' ^ 'o'));
    static_assert(('a' ^ 'e' ^ 'i' ^ 'u'));
    static_assert(('a' ^ 'e' ^ 'o' ^ 'u'));
    static_assert(('a' ^ 'i' ^ 'o' ^ 'u'));
    static_assert(('e' ^ 'i' ^ 'o' ^ 'u'));
    static_assert(('a' ^ 'e' ^ 'i'));
    static_assert(('a' ^ 'e' ^ 'u'));
    static_assert(('a' ^ 'o' ^ 'u'));
    static_assert(('i' ^ 'o' ^ 'u'));
    static_assert(('e' ^ 'i' ^ 'o'));
    static_assert(('a' ^ 'e' ^ 'o'));
    static_assert(('a' ^ 'i' ^ 'u'));
    static_assert(('e' ^ 'o' ^ 'u'));
    static_assert(('a' ^ 'i' ^ 'o'));
    static_assert(('e' ^ 'i' ^ 'u'));

    static size_t findTheLongestSubstring(std::string &s)
    {
        constexpr static unsigned const auVOWEL_LUT[]
        {
            1, //a
            0, 0, 0,
            2, // e
            0, 0, 0,
            4, // i
            0, 0, 0, 0, 0,
            8, // o
            0, 0, 0, 0, 0,
            16, // u
            0, 0, 0, 0, 0
        };
        static_assert(auVOWEL_LUT['a' - 'a']);
        static_assert(auVOWEL_LUT['e' - 'a']);
        static_assert(auVOWEL_LUT['i' - 'a']);
        static_assert(auVOWEL_LUT['o' - 'a']);
        static_assert(auVOWEL_LUT['u' - 'a']);

        size_t azuFirstPosition[32];
        std::fill(std::begin(azuFirstPosition), std::end(azuFirstPosition), std::string::npos);
        azuFirstPosition[0] = 0;

        size_t const n = s.length();

        size_t zuMaxLength = 0;
        unsigned uXor = 0;
        for (size_t i = 0; i < n; ++i)
        {
            char const cChar = s[i];

            uXor ^= auVOWEL_LUT[cChar - 'a'];

            if (azuFirstPosition[uXor] == std::string::npos)
            {
                azuFirstPosition[uXor] = i + 1u;
            }
            else
            {
                zuMaxLength = std::max<size_t>(zuMaxLength, i - azuFirstPosition[uXor] + 1u);
            }
        }

        return zuMaxLength;
    }
};
15400