Module: Hashing


Problem

1/8

Theory Click to read/hide

Hash Function ist eine Funktion, die ein Objekt in eine Kampflinie fester Länge verwandelt. Objekte sind oft ungenau, d.h. Massen, Linien usw.
Im Allgemeinen ist Hex-Funktion eine Druckfunktion, d.h. die Kampflinie ist weniger Information als das ursprüngliche Objekt.
Ist die aufgezeichnete Länge der Schlachtlinie klein, so muss die zerbrochene Linie als unkritische Zahl dargestellt und gespeichert werden. Olympiad-Programmierung bedeutet immer, dass, so werden wir in der Zukunft nur die Tatsache berücksichtigen, dass Hexenakt das Objekt eine Zahl macht.

perfekt. Wir wollen folgende Eigenschaften erfüllen:
(1) Die gleichen Objekte hatten dieselbe xash
(2) Sind die Objekte identisch, so sind die Objekte selbst gleich.

Der erste ist einfach, es ist genug, um den allgemein bestimmten Algorithmus zu fragen.
Aber... Zweite Probleme♪ Wie oben erwähnt, komprimiert Hesh Fusion Objekte. Deshalb arbeitet hier das Dirichle-Prinzip - es wird Fälle geben, in denen zwei verschiedene Objekte den gleichen Fuß haben werden. Das nennt man Konflikt.
Die Hash-Funktionen sind "gut" und "schlecht". "Gut" bietet eine kleine Konfliktwahrscheinlichkeit, aber es ist oft schwierig zu beweisen. Diese Beweise werden auch fallen gelassen.

Pulmonary Xashing:
Wir betrachten den Algorithmus, der eine Sequenz (nummeriert) der Zahlen hat. Die Pfeile fallen auch in diese Definition, einfach unter Berücksichtigung des Symbols als seinen ASCII-Code (der Software-Code ändert nichts, weil die Symbole bereits als Zahlen gespeichert sind).
Zur Berechnung der Schärfenfolge der S-Länge n werden wir folgendes Design berücksichtigen:

pnS0) + pn-1* S1 +n-1 + Sn

wobei p die formale Variable ist.
Ich meine, wir haben S-Sequenz an ein Polynom angepasst.

[Bitte beachten Sie, dass Sie auf anderen Ressourcen im Internet ein weiteres Mitglied sehen können, nämlich S.0) + p * S1 + pn-1 * Sn-1 + pn * SnEs ist auch der richtige Weg, aber ich empfehle die Verwendung der obigen Formel, da es helfen wird, das Hashing der Substrate zu vermeiden, über die wir später sprechen werden.]

Jetzt eine Sash aus S-Sequenz zu bekommen, Legen Sie etwas p in diesen Poly.die als Erde bezeichnet wird. Gleichzeitig werden alle Berechnungen vorgenommen. Änderung (d.h. von jedem arithmetischen Betrieb nehmen wir den Rest der mod Split, die als Modul bezeichnet wird.

Mods Parameter fragt nur, wie viel unsere Hex-Funktion die Sequenz komprimiert. Je mehr Mod ist, desto größer sind die möglichen Hesh-Werte. Und je mehr möglicher Schlauch, desto weniger Wahrscheinlichkeit des Konflikts.
Sagen wir, wir müssen mit tausend Linien arbeiten, von denen jeder denkt, ein Schlauch. Wenn wir ein Modul kleiner als 1.000 nehmen, gibt es ein paar Zeilen in Dyrichle, die dasselbe Chaos haben. So wollen wir immer das größte mögliche Modul wählen. Aber wir vergessen nicht, dass wir mit Zahlen arbeiten, weil es schneller und einfacher ist.

Die Parameter p und mod werden im Voraus ausgewählt. Es wird empfohlen, eine Mod gleich einer einfachen Zahl auszuwählen. Angesichts der vorstehenden Ausführungen wäre es gut, im Bereich 10 eine einfache Zahl zu nehmen.ANHANGso dass Zwischenwiedergabevorgänge lang angelegt werden.
Die Grundlage ist nicht sehr beschränkt auf die Wahl, aber ich würde eine kleine Zahl empfehlen.
[In allen chashing Aufgaben habe ich eine einfache Nummer im Bereich 10 gewählt6und Gesamtzahl im Bereich 10ANHANG Für das Modul war es nie möglich, darunter echte Olympiade. Es gibt jedoch mehrere Blogs auf dem Kraftcode, die dazu bestimmt sind, wie man Parameter für das Heshing abholt und wie man Aufgaben aufbricht, die die Parameter kennen. Wenn du willst, kannst du sie sehen.

Wie sieht es im echten Code aus?
Wir verwenden Gorners Schema, um Hash zu berechnen.
[Wenn du nicht weißt, was es ist, kannst du es lesen. Allgemeine Theorieaber es könnte schwierig sein. Ich empfehle zwei Videos:
(1)Beispiel der Papierzahl
(2)Offenlegung von Formel und Pseudokod
!

lange calc_hash(const string bestandteil s, long p, long mod) {
Länge h = 0;
für (int i = 0; i À s.size(); i++)
h = (h * p + (lang) s[i]) % mod;
♪
Rückkehr h;
♪
Hier ist eine Option, die xash aus der Zeile zu berechnen. Alles wird in der gleichen Weise für die Meißelmassen getan.

Es gibt auch einen Weg, die Wahrscheinlichkeit von Konflikten zu reduzieren. Es ist nur, dass wir die Sequenz eines anderen Parameterpaares blockieren müssen. Für eine Sequenz müssen wir die Xash für die Parameter zählen.1mod1und Parameter (p)2mod2) Dadurch erhalten Sie ein paar Schläuche.1, h2)
In diesem Fall wird es bequem sein, alles paarweise zu halten: Basis (p)1, p2Modul (mod)1mod2) und das Ergebnis der xash wird (h)1, h2) Es wird empfohlen, dass die erforderlichen Dampfbetreiber im Voraus zurückgezahlt werden und dass der Code dann ohne Kopierpaste für die erste und zweite geschrieben werden könnte, als ob er auf den Zahlen betrieben wird.

Berücksichtigen Sie jedoch die Overhead-Kosten der Verwendung von Paaren und was Sie jetzt doppelt so viel wie die Operationen.

Was machen wir dagegen?
Der Hauptzweck der Hash in der Olympischen Programmierung ist eine schnelle Überprüfung der Gleichheit großer Objekte.
Der naive Vergleich der Massen und Linien erfolgt über die Zeit mit ihrer Größe.

Sehen wir folgendes: Sie haben eine Reihe von m Linien, von denen jede die Länge von n ist. Sie haben Q-Anfragen, von denen jeder Sie bitte zu sagen, ob die beiden Zeilen des Kits gleich sind.
Angenommen m = 1.000, n = 1.000, q = 1000000.
Dann wird die naive Entscheidung für O(q*n) arbeiten ~=10ANHANG♪ Sie können die Antwort für jedes Paar von Zeilen vorurteilen und dann können Sie die Anfrage im Moment beantworten, aber es funktioniert für O(m).2*n + q) ~=10ANHANGDas ist zu lange.
Wir benutzen das Jashing, wir hängen jede Linie und für jede Anfrage vergleichen wir den Schlauch anstelle der Leitungen. Es funktioniert für O(m*n + q) ~=106Das ist schnell genug.

Hier zählen wir auf die zweite Eigenschaft, die am Anfang betrachtet wurde. Mit viel Wahrscheinlichkeit beschäftigen wir uns mit den gleichen Objekten, also wählen wir hier eine Top-Strategie. Aber es ist immer noch wichtig zu verstehen, dass du vielleicht nicht in der Lage sein könntest [mit doppeltem Heshing, ich hatte nie so etwas mit dem Üblichen, aber es ist nicht wahr].

Problem

Sie haben t Anfragen, von denen jeder gibt Ihnen eine Zeile s, bestehend aus harten lateinischen Buchstaben, Nummer p und Nummer mod.
Für jede Anforderung berechnen Sie eine Polynom-Xash mit einem p basierend auf mod-Modul aus einer Zeile s, in der jeder Buchstabe erzeugt wird. Ich meine, wenn s = "isaac", musst du das "Iissaaac" zählen.

Eingabe:
In der ersten Zeile ist die Zahl t die Anzahl der Anfragen.
Das folgende t ist die Linie, die jeweils durch die lacuna s gegeben wird (1 Kanal = окsок5.) und mod (1 RP= mod PER= 10.8))

Ausgangsdaten:
Beantworten Sie die Abfragen, jeweils in einer separaten Zeile.

Beispiel:
EingangsdatenAusgangsdaten
2
isaac 12345 87654321
Neuton 54321 12345678
8829000
963-2318