Algoritmo

14

Suponha que recebamos inteiros distintos a 1 , a 2 , ... , a n , de modo que 0 a ik n para alguma constante k > 0 e para todos i .na1,a2,,an0aiknk>0Eu

Estamos interessados ​​em encontrar as contagens de todas as possíveis somas em pares . ( i = j é permitido).Sij=ai+aji=j

Um algoritmo é construir o polinômio de grau k n , e calcular seu quadrado usando o método de transformação de Fourier e ler as potências com seus coeficientes no polinômio resultante. Este é um algoritmo de tempo O ( n log n ) .P(x)=j=1nxajknO(nregistron)

Eu tenho duas perguntas:

  • Existe um algoritmo que não usa FFT?O(nregistron)

  • Algoritmos melhores são conhecidos (ou seja, )? (FFT permitido).o(nregistron)

Aryabhata
fonte
Por que é importante não usar FFT? Parece que você já tem uma boa solução para o seu problema. De onde vem o requisito de não usar a FFT? Isso me parece um requisito bastante natural de impor.
DW
@ DW: Porque então não haverá uma pergunta a fazer? :-) Estou curioso para saber se existe uma abordagem diferente.
Aryabhata 28/05
OK, entendi! Eu admito que também estou curioso. :-) Obrigado pela pergunta interessante.
DW
@DW: De nada :-)
Aryabhata

Respostas:

8

Parece que esse problema é equivalente ao número inteiro / quadrado polinomial:

1. Sabe-se que a multiplicação polinomial é equivalente à multiplicação inteira .

2. Obviamente, você já reduziu o problema ao quadrado polinomial / inteiro; portanto, esse problema é no máximo tão difícil quanto quadrático.

Agora vou reduzir o quadrado inteiro para esse problema:

Suponha que você tenha um algoritmo:

F(uma)P2(x),Onde P(x)=umaEuumaxumaEu

Esse algoritmo é essencialmente o algoritmo que você solicita na sua pergunta. Assim, se eu tivesse um algoritmo mágico que possa fazer isso, eu posso criar uma função, que quadrará o número inteiro y ( oh sim, eu amo mathjax: P ):SQvocêUMARE(y)y

Algoritmo 1 Squaring1:procedimento SQvocêUMARE(y):2):uma() uma começa como uma sequência polinomial vazia3):Eu0 04):WhEueue y0 0 do pausa y para baixo em um polinômio de base 25):Euf y & 1 then se lsb de y está definido6:umaumaEu acrescentar Eu para uma (anexando xEu)7):end Euf8):EuEu+19:yy1 mudança y certo por um10):end WhEueue11):P2(x)F(uma) obter o polinômio ao quadrado via F(uma)12):retvocêrn P2(2) basta resumir o polinômio13):procedimento final

Python ( teste com o codepad ):

#/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. Portanto, a quadratura é no máximo tão difícil quanto esse problema.

4. Portanto, o quadrado inteiro é equivalente a esse problema. (cada um deles é tão duro quanto o outro, devido a ( 2 , 3 , 1 ))

O(nregistron)O(nregistronregistroregistron)O(nregistron2O(registron))Ω(nregistron)

O(nregistron)

5. Agora, seu problema não é exatamente a multiplicação, é o quadrado. Então, a quadratura é mais fácil? Bem, é um problema em aberto (não por enquanto) : sabe-se que o quadrado tem um algoritmo mais rápido que a multiplicação. Se você pudesse encontrar um algoritmo melhor para o seu problema do que usar multiplicação; então isso provavelmente seria um avanço.

O(nregistron)O(nregistron)O(nregistron)O(nregistron) também, como o melhor algoritmo de multiplicação se aproxima apenas dessa complexidade.

Realz Slaw
fonte