Informatyczny kącik olimpijski
Wielomian
W tym miesiącu omówię zadanie Wielomian, które pojawiło się na finale Potyczek Algorytmicznych w 2005 roku.
Zadanie 1. Dany jest wielomian stopnia (co najwyżej)
zdefiniowany poprzez jego wartości w punktach
Naszym zadaniem jest wyznaczenie wartości tego wielomianu w punkcie
Oznaczmy współczynniki wielomianu przez ciąg liczb
gdzie
oznacza współczynnik przy
Najprostszym sposobem rozwiązania tego zadania jest wyznaczenie współczynników wielomianu
rozwiązując następujący układ równań liniowych:

Można to zrealizować za pomocą metody eliminacji Gaussa. Niestety, ten algorytm jest zbyt powolny, ponieważ wykonuje on operacji na liczbach, które mogą rosnąć wykładniczo. Metodę tę można jednak znacznie przyśpieszyć, wykorzystując fakt, że znamy wartości wielomianu
w punktach będących kolejnymi liczbami naturalnymi.
Dowód. Skoro funkcje oraz
są wielomianami, to również funkcja
jest wielomianem. Współczynnik wielomianu
przy
wynosi
Natomiast dla wielomianu
mamy:

Skoro to współczynnik przy
wielomianu
także jest równy
Z tego wynika, że współczynnik przy
wielomianu
jest równy
Korzystając z lematu 1, możemy zredukować stopień wielomianu uzyskując problem równoważny. Aby to zrobić, zdefiniujmy ciąg wielomianów
taki że
oraz
dla
oraz
Powstały w ten sposób wielomian
ma stopień
zatem
Znając wartość wielomianu
w kolejnym punkcie, możemy obliczyć wartości
dla
bezpośrednio z definicji ciągu wielomianów
Obliczając nowe wartości kolejnych wielomianów, za każdym razem do poprzednio otrzymanej wartości dodajemy
zatem:

Spróbujmy teraz zapisać w zależności od wartości
Skoro jedynymi operacjami, jakie wykonujemy, są dodawanie i odejmowanie, to wszystkie otrzymane liczby będą liniowo zależne od wartości wielomianu
Możemy, korzystając z definicji ciągu wielomianów
zapisać:
![]() |
oraz w ogólności:

Zachęcam Czytelnika, aby sprawdził poprawność tego wzoru i spróbował go udowodnić za pomocą indukcji matematycznej. Po wstawieniu tej równości do wzoru otrzymanego w poprzednim akapicie dostajemy:
![]() |
Dowód. Udowodnimy ją za pomocą indukcji względem Dla
mamy

W kroku indukcyjnym korzystamy z tożsamości:
![]() |
Na podstawie lematu 2 otrzymujemy dla :
![]() |
Dzięki tożsamości

możemy obliczyć powyższą sumę, wykonując liniową ilość operacji na liczbach całkowitych.
Wartości składników tej sumy mogą być bardzo duże, więc dodatkową trudność w tym zadaniu są operacje na dużych liczbach. Na szczęście potrzebujemy jedynie wykonywać sumowanie dużych liczb oraz mnożenie i dzielenie dużych liczb przez małe. Obie te operacje można łatwo zrealizować w czasie liniowym względem długości liczby. Zatem ostatecznie otrzymujemy złożoność czasową