Казалось бы, эта проблема эквивалентна целочисленному / полиномиальному квадрату:
1. Известно, что полиномиальное умножение эквивалентно целочисленному умножению .
2. Очевидно, вы уже свели задачу к полиномиальному / целочисленному квадрату; поэтому эта проблема не более, чем квадрат.
Теперь я приведу целочисленный квадрат к этой задаче:
Предположим, у вас был алгоритм:
F( а⃗ ) → P2( х ) ,где П( х ) = ∑aя∈ a⃗ Иксaя
Этот алгоритм по сути является алгоритмом, который вы запрашиваете в своем вопросе. Таким образом, если бы у меня был магический алгоритм, который может это сделать, я мог бы создать функцию которая возведет в квадрат целое число y ( о да, я люблю mathjax: P ):S Q U A R E ( у)Y
1 .:2 .:3 .:4 .:5 .:6 .:7 .:8 .:9 .:10 .:11 .:12 .:13 .:Алгоритм 1 Квадратпроцедура S Q U A R E ( у) :a⃗ ← ( )я ← 0ж ч я л е г ≠ 0 д о я ф Y & 1 т ч е н a⃗ ← а⃗ яе н д я ф я ← я + 1Y← у≫1end whileP2(x)←F(a⃗ )return P2(2)end procedure▹ a⃗ starts as empty polynomial sequence▹ break y down into a polynomial of base 2▹ if lsb of y is set▹ append i to a⃗ (appending xi)▹ shift y right by one▹ obtain the squared polynomial via F(a⃗ )▹ simply sum up the polynomial
Python ( тест с кодовой панелью ):
#/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. Таким образом, возведение в квадрат не более, чем эта проблема.
4. Следовательно, целочисленное возведение в квадрат эквивалентно этой задаче. (каждый из них не более, чем друг с другом, из-за ( 2 , 3 , 1 ))
O(nlogn)O(nlognloglogn)O(nlogn2O(log∗n))Ω(nlogn)
O(nlogn)
5. Теперь ваша проблема не в умножении, а в квадрате. Так проще ли возводить в квадрат? Что ж, это открытая проблема (на данный момент нет) : неизвестно, что в квадрате используется более быстрый алгоритм, чем умножение. Если бы вы могли найти лучший алгоритм для вашей задачи, чем использование умножения; тогда это, вероятно, будет прорывом.
O(nlogn)O(nlogn)O(nlogn)O(nlogn) либо, поскольку лучший алгоритм умножения только приближается к этой сложности.