Algoritmo

14

Supongamos que se nos dan enteros distintos , de modo que para alguna constante , y para todo .na1,a2,,an0aiknk>0i

Estamos interesados ​​en encontrar los recuentos de todas las sumas por parejas posibles . ( está permitido).Sij=ai+aji=j

Un algoritmo es construir el polinomio de grado , y calcular su cuadrado utilizando el método de transformación de Fourier y leer las potencias con sus coeficientes en el polinomio resultante. Este es un algoritmo de tiempo .P(x)=j=1nxajknO(nlogn)

Tengo dos preguntas:

  • ¿Existe un algoritmo que no use FFT?O(nlogn)

  • ¿Se conocen mejores algoritmos (es decir, )? (FFT permitido).o(nlogn)

Aryabhata
fuente
¿Por qué es importante no usar FFT? Parece que ya tienes una buena solución a tu problema. ¿De dónde viene el requisito de no usar FFT? Eso me parece un requisito poco natural de imponer.
DW
@DW: ¿Porque entonces no habrá una pregunta que hacer? :-) Tengo curiosidad por saber si hay un enfoque diferente.
Aryabhata
¡Ok lo tengo! Admito que también tengo curiosidad. :-) Gracias por la interesante pregunta.
DW
@DW: De nada :-)
Aryabhata

Respuestas:

8

Parece que este problema es equivalente a la cuadratura entera / polinómica:

1. Se sabe que la multiplicación polinómica es equivalente a la multiplicación entera .

2. Obviamente, ya redujo el problema a cuadratura polinómica / entera; por lo tanto, este problema es tan difícil como cuadrar.

Ahora reduciré la cuadratura entera a este problema:

Supongamos que tienes un algoritmo:

F(a)P2(x),where P(x)=aiaxai

Este algoritmo es esencialmente el algoritmo que solicita en su pregunta. Por lo tanto, si tuviera un algoritmo mágico que pueda hacer esto, puedo hacer una función, que cuadrará el número entero y ( oh sí, amo mathjax: P ):SQUARE(y)y

Algorithm 1 Squaring1.:procedure SQUARE(y):2.:a() a starts as empty polynomial sequence3.:i04.:while y0 do break y down into a polynomial of base 25.:if y & 1 then if lsb of y is set6.:aai append i to a (appending xi)7.:end if8.:ii+19.:yy1 shift y right by one10.:end while11.:P2(x)F(a) obtain the squared polynomial via F(a)12.:return P2(2) simply sum up the polynomial13.:end procedure

Python ( prueba con teclado ):

#/cs//q/11418/2755

def F(a):
    n = len(a)
    for i in range(n):
        assert a[i] >= 0

    # (r) => coefficient
    # coefficient \cdot x^{r}
    S = {}
    for ai in a:
        for aj in a:
            r = ai + aj

            if r not in S:
                S[r] = 0

            S[r] += 1

    return list(S.items())

def SQUARE(x):
    x = int(x)

    a = []
    i = 0
    while x != 0:
        if x & 1 == 1:
            a += [i]
        x >>= 1
        i += 1

    print 'a:',a
    P2 = F(a)

    print 'P^2:',P2

    s = 0
    for e,c in P2:
        s += (1 << e)*c
    return s

3. Por lo tanto, la cuadratura es tan difícil como este problema.

4. Por lo tanto, la cuadratura entera es equivalente a este problema. (cada uno es tan duro como el otro, debido a ( 2 , 3 , 1 ))

O(nlogn)O(nlognloglogn)O(nlogn2O(logn))Ω(nlogn)

O(nlogn)

5. Ahora, su problema no es exactamente la multiplicación, es la cuadratura. Entonces, ¿es más fácil la cuadratura? Bueno, es un problema abierto (no por ahora) : no se sabe que la cuadratura tenga un algoritmo más rápido que la multiplicación. Si pudiera encontrar un mejor algoritmo para su problema que usar la multiplicación; entonces esto probablemente sería un gran avance.

O(nlogn)O(nlogn)O(nlogn)O(nlogn) tampoco, ya que el mejor algoritmo de multiplicación solo se acerca a esa complejidad.

Ensalada Realz
fuente