Count number of pairs of strings which on joining contain all vowels Problem

I have \$N\$ words. For each valid \$i\$, word \$i\$ is described by a string \$D_i\$ containing only lowercase vowels, i.e. characters 'a', 'e', 'i', 'o', 'u'. 

We check the number of strings \$D_i\$ and \$D_j\$ which, when concatenated into a new string \$M\$, contain all 5 vowels. What is the total number of (unordered) pairs of words such that when concatenated, they contain all the vowels?

Input


The first line of the input contains a single integer \$T\$ denoting the number of test cases. The description of \$T\$ test cases follows.
The first line of each test case contains a single integer \$N\$.
\$N\$ lines follow. For each valid \$i\$, the \$i^{th}\$ of these lines contains a single string \$D_i\$.


Output

For each test case, print a single line containing one integer - the number of concatenated words that contain all vowels.

Test Case

3
aaooaoaooa
uiieieiieieuuu
aeioooeeiiaiei


Output

2


Constraints


\$1≤T≤1,000\$
\$1≤N≤10^5\$
\$1≤|D_i|≤1,000\$ for each valid \$i\$
the sum of all |\$D_i\$| over all test cases does not exceed \$3⋅10^7\$


I have written some code but I want to optimize it:

#include&lt;bits/stdc++.h&gt;
using namespace std;

int main()
{
  int t;
  cin&gt;&gt;t;
  while(t--)
  {
    int n;
    cin&gt;&gt;n;
    vector&lt;string&gt; v;
    long long  con_s[n];
    for(int i=0;i&lt;n;i++)
    {
      string s;
      cin&gt;&gt;s;
      con_s[i]=0;
      for(int j=0;j&lt;s.length();j++)
      {
        con_s[i] = con_s[i] | (1&lt;&lt;(s[j]-'a'));
      }
    }
    long long complete = 0;
    complete = (1&lt;&lt;('a'-'a')) | (1&lt;&lt;('e'-'a')) | (1&lt;&lt;('i'-'a')) | (1&lt;&lt;('o'-'a')) | (1&lt;&lt;('u'-'a'));
    // cout&lt;&lt;complete;
    int count = 0;
    for(int i=0;i&lt;n-1;i++)
    {
      for(int j=i+1;j&lt;n;j++)
      {
        if((con_s[i] | con_s[j])==complete)count++;
      }
    }
    cout&lt;&lt;count&lt;&lt;"\n";
  }
  return 0;
}


Can you please suggest a more optimized solution...
Your Code:


Don't use &lt;bits/stdc++.h&gt;, it's unportable and inefficient. See "Why should I not #include &lt;bits/stdc++.h>?" for the details.
Don't use using namespace std;, that namespace just isn't designed for it. See "Why is “using namespace std” considered bad practice?" for more background.
Invest in some better names. Being too parsimonious there hurts, even though brevity is a virtue.
Format your code consistentently.


Sometimes you have space around binary operators (other than comma, which only should be followed by a space), sometimes you forget.
Add a space after ; when it isn't followed by the next line, meaning a loop's head.
Also add a space after #include, for, if, and while.
You don't have to use a block for single statements, but please don't put them on the same line, at the least separate them with a space.

C++ does not have VLAs. Just use a std::vector instead.
While in general, keeping the scope of a variable minimal is a good idea, there are exceptions. One of them is efficiency. Always spinning up a new std::string means being unable to re-use the buffer. Not that you really need the whole string at once, anyway.
One reason you should minimise a variables scope, is that it allows you to initialise it to the proper value, instead of leaving it uninitialised or, horrors of horrors, adding a spurious dummy-initialisation.
That also allows you to avoid writing the type (Almost Always auto), and making it const or even constexpr.
There are compound-assignment-operators for most binary operators. Like a |= b for a = a | b. Using them leads to shorter, more readable code.
When you want to output a single character, why not use a character-literal? It's potentially even slightly more efficient.
return 0; is implicit for main(). Take it or leave it, but be aware.


The Algorithm:

Your algorithm uses \$O(\#characters+\#words^2)\$ time and \$O(max\_word\_length + \#words)\$ space.

An optimal algorithm only needs \$O(\#characters+2^{\#vowels})\$ time and \$O(2^{\#vowels})\$ space:


For every word:


Set the bits for all the vowels contained.
Increment the count on the indicated bin.

For every vowel:


Iterate the bins containing words with that vowel.
Add the count to the respective bin without that vowel.

For all bins:
Multiply the count in the bin with the count in the complementary bin, and add that.
Subtract twice the count in the bin for words containing all vowels. Those account for all self-pairings.
The answer is half the calculated number, as we counted double.


Exercise for the attentive reader: Save half the multiplications this algorithm uses.