#149 Yo ayer estuve pensando en una idea para hacerlo nlogn, pero no consigo acabar de pulirla, te la cuento por si quieres seguir o pensarla.
Definimos dos arrays, S y P
S[ i ] = numero de elementos del array menores o iguales a i
P[ i ] = numero de parejas que su suma es menor o igual a i
S y P pueden calcularse en tiempo lineal, inicialmente asignamos S[ i ] = ocurrencias de i en el array y para cada a[ i-1 ] + a[ i ] sumamos i a P[ a[ i-1 ] + a[ i ] ] .
Luego con un for sumamos S[ i - 1 ] a S[ i ], y lo mismo con P. Con esto no es dificil ver que consigues S y P en tiempo lineal con dos pasadas al array. Esto ultimo es porque si a < b entonces a < b + 1.
Ahora considera S y P como polinomios. El producto de S y P es un polinomio T tal que
T[ k ] = sum (i + j = k) S[ i ] * P[ j ]
o en otras palabras T[ i + j ] contiene el numero de tripletes a,b,c tales que a + b + c <= i + j.
Con la FFT podemos pasar los polinomios a point-value form en O(nlogn) rapidamente, y multiplicando elemento a elemento las transformadas obtenemos T en point-value form. Haciendo la transformada inversa obtenemos T en forma de coeficiente. Si hay un i tal que T[ i ] > T[ i - 1 ] entonces existe un triplete que suma exactamente i.
El problema? T tambien contiene los tripletes de la forma ai,,ai,aj, y no se descartarlos. Tampoco te permite rescatar que triplete da la suma. Pero me parece interesante compartirlo por si a alguien se le ocurre (y se aburre lo bastante) una forma de arreglarlo.
Esto es asumiendo que los numeros que salen en el array estan acotados linealmente por el tamaño de la entrada. También puede probarse a hacerse con programación dinámica, pero con eso creo que te quedaría cuadrático, como con la solución de hashing.