Informatyka

Tematy zajęć olimpijskich

Wprowadzenie do informatyki i narzędzi matematycznych

  1. Czym jest informatyka i algorytm? – wstęp teoretyczny: czym zajmuje się informatyka, pojęcie algorytmu, przykłady prostych procedur krok po kroku.
  2. Informacja i reprezentacja danych – bity i bajty, systemy liczbowe, reprezentacja znaków (ASCII, Unicode), podstawy przechowywania i przesyłania informacji.
  3. Złożoność obliczeniowa – intuicja, jak mierzyć czas działania algorytmów, notacja dużego O, podstawowe klasy złożoności, przykłady z praktyki.
  4. Logika i rozumowanie algorytmiczne – operatory logiczne, implikacja i równoważność, proste zagadki logiczne, wprowadzenie do inwariantów i dowodzenia poprawności algorytmów.
  5. Arytmetyka modulo, NWD i NWW – działanie w arytmetyce modularnej, algorytm Euklidesa.
  6. Kombinatoryka – permutacje, wariacje, kombinacje, współczynnik dwumienny, wzór dwumienny Newtona, podstawowe techniki liczenia możliwości.
  7. Maszyna Turinga / Model obliczeń – idea abstrakcyjnej maszyny obliczeniowej, granice tego, co da się obliczyć, przykłady problemów obliczalnych i nieobliczalnych.

Programowanie w C++ – podstawy i narzędzia

  1. Wprowadzenie do systemu linux.
  2. Wprowadzenie do języka C++ – historia i charakterystyka języka, kompilacja i uruchamianie programów, podstawy środowiska programistycznego.
  3. Pierwszy program, typy danych i zmienne, instrukcje wejścia/wyjścia, komentarze, struktura prostego programu, typy podstawowe, konwersje typów.
  4. Operatory i instrukcje sterujące – operatory arytmetyczne, logiczne i porównania; instrukcje warunkowe if, else, switch.
  5. Pętle – for, while, do…while; przykłady zastosowań (sumy, silnie, tablice).
  6. Wskaźniki i referencje – podstawy wskaźników, różnice między wskaźnikiem a referencją, proste zastosowania.
  7. Tablice i napisy – tablice jednowymiarowe, podstawy pracy z napisami (string), operacje na elementach.
  8. Funkcje – deklaracja i definicja funkcji, parametry i wartości zwracane, zasięg zmiennych, rekurencja (podstawy).
  9. Struktury i typy złożone – struct, proste rekordy danych, metody w strukturach, wprowadzenie do programowania zorganizowanego.
  10. Wprowadzenie do STL i para (pair) – idea szablonów, pair, operacje porównania i praktyczne zastosowania.
  11. Kontenery sekwencyjne I – vector – tworzenie, dodawanie/usuwanie elementów, indeksowanie, iteratory, typowe błędy i zastosowania.
  12. Kontenery sekwencyjne II – deque, stack, queue – kolejka i stos jako adaptery kontenerów, różnice między deque a vector, przykłady użycia.
  13. Kontenery asocjacyjne I – set, multiset, bitset – operacje podstawowe, unikalność elementów, iteratory, użycie bitset do problemów algorytmicznych.
  14. Kontenery asocjacyjne II – map, multimap – pary klucz-wartość, iteratory, operacje wstawiania i wyszukiwania.
  15. Hashowane wersje – unordered_map, unordered_set – różnice względem klasycznych map i setów, złożoność operacji, typowe zastosowania.
  16. Algorytmy STL – sortowanie (sort), wyszukiwanie binarne (binary_search, lower_bound, upper_bound), generowanie permutacji (next_permutation), przykłady problemów.
  17. Dobre praktyki i styl pisania kodu – czytelność kodu, komentarze, unikanie błędów początkujących, debugowanie, podstawy profilowania.

Podstawowe algorytmy i techniki

  1. Sumy prefiksowe – idea sum prefiksowych i tablic różnicowych; zastosowania do szybkiego liczenia sum podprzedziałów; przykłady praktyczne.
  2. Technika dwóch wskaźników – przesuwane wskaźniki (two pointers); znajdowanie przedziałów spełniających warunki; zastosowania w zadaniach optymalizacyjnych.
  3. Sortowania proste – sortowanie przez wstawianie, bąbelkowe i wybieranie; analiza złożoności; sytuacje, w których mimo wszystko mogą być przydatne.
  4. Sortowania szybkie – mergesort i quicksort; idea „dziel i zwyciężaj”; praktyczne użycie std::sort i jego złożoność.
  5. Sortowania specjalne – sortowanie przez zliczanie, sortowanie kubełkowe, radix sort; ograniczenia i zastosowania przy danych liczbowych.
  6. Algorytmy zachłanne – konstrukcja rozwiązania krok po kroku; przykłady: wybór aktywności, budowanie największej liczby z cyfr; dowodzenie poprawności algorytmów zachłannych.
  7. Wyszukiwanie binarne – idea binarnego przeszukiwania; implementacja klasyczna; warianty (lower_bound, upper_bound); typowe błędy implementacyjne.
  8. Kopiec binarny i kolejka priorytetowa – zasada działania kopca; operacje push/pop; implementacja kolejki priorytetowej (priority_queue w C++); zastosowania.
  9. Kolejka maksimów i minimum – algorytm liniowy do znajdowania maksimum/minimum w oknie przesuwanym; zastosowania w zadaniach na przedziałach.
  10. Divide & Conquer – inne zastosowania – znajdowanie maksimum i minimum w tablicy; problem najbliższej pary punktów; rekurencyjne liczenie inwersji.

Teoria złożoności i granice obliczalności

  1. Notacja asymptotyczna – przypomnienie i pogłębienie – notacje O,Ω,Θ; porównywanie funkcji wzrostu; przykłady algorytmów o różnych złożonościach.
  2. Klasy P i NP – intuicja pojęć: problemy rozwiązywalne w czasie wielomianowym, problemy sprawdzalne w czasie wielomianowym; przykłady typowych problemów z obu klas.
  3. NP-zupełność – idea redukcji problemów; klasyczne przykłady (SAT, klik, plecak, pokrycie wierzchołkowe); znaczenie NP-zupełności w praktyce.
  4. Problemy poza NP i nierozstrzygalność – klasy NP-trudne i PSPACE; problemy nierozstrzygalne (problem stopu, równoważność programów); związki z maszyną Turinga.
  5. Heurystyki i praktyka – co robić z problemami „zbyt trudnymi” (NP-trudnymi); algorytmy zachłanne, przybliżone, randomizowane jako obejście teoretycznych ograniczeń.

Matematyka w algorytmice

  1. Arytmetyka modularna – rozszerzenia – dzielenie modulo, elementy odwrotne, Małe Twierdzenie Fermata, szybkie potęgowanie modulo; praktyczne zastosowania w zadaniach.
  2. Chińskie Twierdzenie o Resztach (CRT) – idea kongruencji, rozwiązywanie układów równań modularnych, przykłady praktyczne.
  3. Liczby pierwsze i sita – sito Eratostenesa i jego warianty (np. liniowe); testy pierwszości (Miller–Rabin); rozkład na czynniki.
  4. Funkcje liczbowo-teoretyczne – funkcja Eulera φ, funkcja Möbiusa μ, podstawy liczenia funkcji multiplikatywnych.
  5. Kombinatoryka – rozszerzenia – zasada inkluzji–ekskluzji; liczenie podzbiorów i permutacji z powtórzeniami; generowanie struktur kombinatorycznych.
  6. Prawdopodobieństwo w algorytmice – podstawy rachunku prawdopodobieństwa; algorytmy randomizowane (Monte Carlo i Las Vegas) jako praktyczne zastosowania.

Algorytmy na grafach

  1. Reprezentacje grafów – macierz sąsiedztwa, listy sąsiedztwa, wybór reprezentacji pod kątem złożoności.
  2. DFS i BFS – przeszukiwanie w głąb i wszerz; kolejka i stos w implementacji; zastosowania w prostych zadaniach.
  3. Własności grafów nieskierowanych – komponenty spójności, cykle, drzewa i lasy.
  4. Grafy skierowane – silnie spójne składowe (SCC); algorytmy Kosaraju i Tarjana.
  5. Sortowanie topologiczne – definicja DAG, algorytmy (DFS + Kahn), zastosowania w zadaniach porządkowych.
  6. Algorytmy jednokrotnego źródła – Dijkstra (tablica + kopiec), Bellman–Ford.
  7. Algorytmy wieloźródłowe – Floyd–Warshall; zastosowania do pełnych macierzy odległości.
  8. Najkrótsze ścieżki w DAG – dynamiczne podejście na grafach acyklicznych.
  9. Drzewa rozpinające (MST) – Kruskal, Prim, porównanie algorytmów; zastosowania praktyczne.
  10. Wyszukiwanie centroidu i centroid decomposition – dzielenie drzewa na części; przykłady zastosowań.
  11. Binary Lifting i LCA – algorytmy do znajdowania najniższego wspólnego przodka; zastosowania w zapytaniach na drzewach.
  12. Euler Tour i Heavy-Light Decomposition (HLD) – techniki reprezentacji drzew do obsługi zapytań.
  13. Mosty i punkty artykulacji – definicja, algorytm Tarjana; dwuspójne składowe.
  14. Grafy planarne – twierdzenie Eulera, wykrywanie planarnych grafów, graf dualny, zastosowania w zadaniach optymalizacyjnych.
  15. Cykl Eulera i ścieżka Hamiltona – różnice między problemami, algorytm Hierholzera; trudność Hamiltona.
  16. Grafy dwudzielne – sprawdzanie dwudzielności; dopasowania w grafach dwudzielnych.
  17. Algorytmy przepływu – Ford–Fulkerson, Edmonds–Karp, Dinic; zastosowania w dopasowaniach i problemach sieciowych.
  18. Dopasowania ogólne – matching w grafach dwudzielnych (Hungarian, Hopcroft–Karp); wzmianka o Edmonds Blossom.

Programowanie dynamiczne

  1. Wprowadzenie do DP – idea pamiętania wyników, różnica między tablicowaniem a memoizacją; przykłady prostych rekurencji.
  2. Klasyczne ciągi i zadania 1D – Fibonacci, liczby Catalana, proste optymalizacje liniowe.
  3. Plecak (knapsack) – 0/1 knapsack, unbounded knapsack, różne warianty i ich zastosowania.
  4. Najdłuższy wspólny podciąg (LCS) – rekurencja, tablica 2D, odtwarzanie rozwiązania.
  5. Najdłuższy rosnący podciąg (LIS) – rozwiązanie O(nlogn), powiązania z grafami.
  6. Problemy rozdzielania i podziałów – triangulacja wielokąta, optymalne nawiasowanie (matrix chain multiplication).
  7. DP na drzewach – podproblemy na poddrzewach, klasyczne przykłady (maksymalne niezależne wierzchołki, średnica drzewa).
  8. DP na grafach acyklicznych (DAG) – liczenie ścieżek, najdłuższe/ najkrótsze ścieżki w DAG, zastosowania do porządków topologicznych.
  9. DP na planszach i siatkach – klasyczne zadania typu „ścieżki w siatce”, liczenie sposobów przejścia przez kratownicę z przeszkodami.
  10. Divide & Conquer DP – idea dzielenia przestrzeni decyzji, przykłady zastosowań.
  11. Convex Hull Trick – optymalizacja DP liniowych, struktury wspierające.
  12. Knuth i Yao Optimization – specjalne przypadki optymalizacji problemów sekwencyjnych.

Zaawansowane Struktury danych

  1. Tablice haszujące (hash tables) – idea funkcji mieszającej; kolizje i metody ich obsługi; unordered_map i unordered_set w C++; zastosowania praktyczne.
  2. Drzewo Fenwicka (BIT) – implementacja; zastosowania do sum prefiksowych i aktualizacji; złożoność i przewagi nad tablicami prefiksowymi.
  3. Sparse Table – struktura do RMQ i zapytań statycznych; koncepcja preprocesingu; porównanie z Fenwickiem i segment tree.
  4. Segment Tree – podstawy – implementacja drzewa przedziałowego; operacje update i query; zastosowania (suma, minimum, maksimum).
  5. Segment Tree z propagacją leniwą – „lazy propagation” do aktualizacji przedziałowych; przykłady zastosowań.
  6. Segment Tree 2D i warianty – obsługa zapytań na planszach; wady i zalety (złożoność pamięciowa).
  7. Struktury dynamiczne
  8. Union-Find (DSU) – znajdowanie reprezentantów, łączenie zbiorów; optymalizacje (path compression, union by rank); zastosowania w grafach.
  9. Drzewa BST – wprowadzenie – idea drzew poszukiwań binarnych; zrównoważone vs niezrównoważone BST.
  10. Treapy i Splay Trees – losowe równoważenie w treapach; splay trees i analiza amortyzowana.
  11. Struktury zaawansowane na drzewach
  12. Persistent Data Structures – idea niezmienniczości; persistent segment tree; zastosowania w zadaniach offline.
  13. Heavy-Light Decomposition (HLD) – rozbijanie drzewa na ścieżki; obsługa zapytań na ścieżkach w czasie logarytmicznym.
  14. Link-Cut Trees (opcjonalnie) – wprowadzenie do struktury do dynamicznych drzew; zastosowania w problemach konkursowych.

Algorytmy na ciągach i napisach

  1. Naiwne wyszukiwanie i idea prefikso-sufiksów – proste przeszukiwanie liniowe; analiza złożoności; intuicja prefiksów i sufiksów jako wprowadzenie do KMP.
  2. Algorytm Knutha–Morrisa–Pratta (KMP) – formalne wprowadzenie; budowa tablicy pi; implementacja; przykłady zastosowań.
  3. Funkcja Z – definicja, implementacja liniowa; zastosowania w wyszukiwaniu wzorców i analizie napisów.
  4. Rabin–Karp – klasyczny algorytm wyszukiwania wzorca przy użyciu hashy; złożoność i praktyczne użycie.
  5. Suffix Array – idea tablicy sufiksowej; algorytmy konstrukcji; tablica LCP.
  6. Drzewo sufiksowe (Suffix Tree) – idea drzewa sufiksowego; algorytm Ukkonena (wzmianka); porównanie z suffix array.
  7. Tries – budowa drzewa prefiksowego; operacje insert/search; zastosowania w problemach na słowniki.
  8. Aho–Corasick – automatyczne wyszukiwanie wielu wzorców naraz; implementacja z BFS; zastosowania w problemach konkursowych.

Geometria obliczeniowa

  1. Podstawy wektorów i układów współrzędnych – reprezentacja punktów, operacje na wektorach, iloczyn skalarny i wektorowy.
  2. Orientacja punktów i test CCW – sprawdzanie skrętu, położenie punktu względem odcinka, zastosowania w algorytmach.
  3. Pole wielokąta i własności geometryczne – wzór Shoelace, obliczanie pól, testy wypukłości, własności figur.
  4. Triangulacja wielokąta – podział wielokąta na trójkąty; zastosowania w dynamicznym programowaniu i grafice.
  5. Przecięcia odcinków – warunki przecięcia, implementacja, przypadki brzegowe.
  6. Otoczka wypukła (Convex Hull) – algorytm Grahama i Andrew; zastosowania w zadaniach optymalizacyjnych.
  7. Najbliższa para punktów – naiwny algorytm; rozwiązanie „divide & conquer” w O(nlogn).
  8. Algorytmy typu sweep-line – idea zdarzeń i aktywnych obiektów; przecięcia wielu odcinków; zastosowania praktyczne.

Gry i algorytmy kombinatoryczne

  1. Wprowadzenie i gra Nim – gry dwuosobowe z pełną informacją; brak losowości i remisów; klasyczny Nim i twierdzenie Boutona; interpretacja XOR jako strategii wygrywającej.
  2. Teoria Sprague–Grundy – definicja funkcji Grundy’ego; dowód redukcji gry do Nim; przykłady zastosowań.
  3. Gry na grafach – gry w usuwanie krawędzi/wierzchołków, Hackenbush, Kayles; strategie w oparciu o Sprague–Grundy.
  4. Minimax – klasyczny algorytm przeszukiwania drzewa gry; zastosowanie w prostych grach logicznych.
  5. Alpha–Beta Pruning – optymalizacja minimaxu; praktyczne znaczenie w ograniczaniu przestrzeni stanów.

Algorytmy zaawansowane i techniki specjalne

  1. Operacje bitowe w praktyce – manipulacje bitami, maski, szybkie sprawdzanie warunków, zastosowania w problemach kombinatorycznych.
  2. DP na maskach – klasyczne zadania (TSP, liczenie podzbiorów); implementacja i optymalizacje.
  3. Kolejność podzbiorów i subset convolution – iterowanie po wszystkich podzbiorach, triki implementacyjne; idea subset convolution i zastosowania.
  4. Szybkie potęgowanie macierzy – mnożenie macierzy w DP; zastosowania do ciągów i grafów (np. liczenie ścieżek długości k).
  5. FFT i NTT – szybka transformata Fouriera i numeryczna; mnożenie wielomianów i ciągów; zastosowania w zadaniach.
  6. Algorytm Mo – idea offline queries; porządkowanie zapytań, przykład z sumami; analiza złożoności.
  7. Sweep-line w zadaniach ogólnych – technika zdarzeń poza geometrią; zastosowania do przedziałów, zbiorów, zapytań offline.
  8. Dynamiczna spójność i zapytania offline – technika „rollback DSU”, divide & conquer on queries; przykłady problemów konkursowych.