Anstatt nur die xash-Sequenz zu zählen, können wir uns an die Bedeutung jedes seiner Präfixe erinnern. Wir weisen darauf hin, dass dies die xash-Werte für Sequenzen gleich dem entsprechenden Präfix sein werden.
Mit einer solchen Struktur kann der Wert der xash für jeden Teilabschnitt dieser Sequenz (im Gegensatz zu vorgegebenen Mengen) schnell berechnet werden.
Wenn wir die Xash des Schnittes zählen wollen [l;r], müssen wir den Hash auf den Präfix r und die Hash auf den l-1 Präfix nehmen, auf p auf r-l+1. Warum macht das Sinn, wenn Sie das Präfix unterschreiben und sehen, was los ist? Ich hoffe, Sie können sich dieses Bild ansehen.
Durch diese Aktionen erhalten wir einen Hash-Unterabschnitt der Anfangssequenz. Dieser ist jedoch gleich, wenn er als Hexe aus der Sequenz desselben Unterabschnitts betrachtet wurde (keine zusätzlichen Schritte sind erforderlich, oder so weiter, um mit anderen Werten zu vergleichen).
Es gibt zwei Punkte zu klären:
(1) Alle möglichen Stufen des Mod-Moduls p sollten im Voraus vorgegeben werden, um schnell auf p zu r-l+1 zu Hause.
(2) Es muss beachtet werden, dass alle Berechnungen Mod-Module sind, so kann es sein, dass wir nach dem Lesen des präfixierten Hesh eine negative Zahl erhalten. Um dies zu vermeiden, können Sie immer einen Mod hinzufügen, bevor Sie ausgehen. Auch vergessen wir nicht, nach dem Haus und allen Einlagen nehmen wir auch den Modul.
Der Code sieht aus wie:
#include Ébits/stdc++++++.h
mit Namespace std;
Typdef long ll;
const int MAXN = 1000003;
/ Basis- und Heashing-Modul
ll p, mod;
/ Präfix und p
ll h[MAXN], pows[MAXN];
// Berechnung des xash-Unterabschnitts [l;r]
ll get_segment_hash(int l, int r) {
zurück (h[r] + mod - h[l - 1] * pows[r - l + 1] % mod) % mod;
♪
int main()
{~}
/ auf irgendeine Weise empfangen p und mod
/ Betreff des Abschlusses p
pows[0] = 1;
für (int i = 0; i Ø MAXN; i+++)
pows[i] = (pows[i - 1] * p) % mod;
/
/ Schlüssel
/
Rückkehr 0;
♪