[GO] 4 Methoden zum Zählen der Anzahl von Ganzzahlen in einem bestimmten Intervall (einschließlich der imos-Methode) [Python-Implementierung]

Hintergrund

Als ich das ABC127 C-Problem der Wettbewerbsprogrammierung AtCoder löste, dachte ich darüber nach, wie viele gemeinsame Teile in einer Reihe aufeinanderfolgender Ganzzahlen enthalten sind. Ich fand es sehr interessant, weil es verschiedene Lösungen für das Problem gab, also beschloss ich, einen Artikel zu schreiben. Das Problem kann unter dem folgenden Link gefunden werden. Wir erklären auch das ABC127 C-Problem, seien Sie also vorsichtig mit Spoilern.

AtCoder Beginner Contest 127 C - Prison

C - Prison Beginnen wir mit der Problemstellung.

スクリーンショット 2020-07-31 2.49.32.png

Schreiben Sie einen Überblick über die Problemstellung. Es gibt M Tore und Sie benötigen einen Ausweis, um sie zu öffnen. Es gibt N ID-Karten mit den Nummern 1 bis N. Einige Tore können nur ID-Karten mit Nummern über Li und unter Ri öffnen. Es geht darum zu zählen, wie viele ID-Karten vorhanden sind, die alle Tore öffnen können.

Betrachten wir zunächst ein Eingabebeispiel. Es gibt vier ID-Karten mit den Nummern 1, 2, 3 und 4. Es gibt 3 Tore, das 1. Tor kann mit 1, 2 und 3 ID-Karten geöffnet werden und das 2. Tor kann mit 2, 3 und 4 ID-Karten geöffnet werden. Sie können sehen, dass nur 2 und 3 ID-Karten alle Tore öffnen können. Mit anderen Worten, die Idee war, einen Produktsatz von ID-Karten zu nehmen, die alle Tore öffnen konnten.

Betrachten eines Satzes unter Verwendung der Satzrichtlinie 1

Zusammenfassend lässt sich sagen, dass diese Methode viel Rechenzeit in Anspruch nahm und zu TLE wurde und nicht bestand.

In der Regel werden die Informationen zu Minimalwert und Maximalwert der ID-Kartennummer, die ein Tor öffnen können, in einer Zeile eingegeben. Erstellen Sie daher die Nummer vom Minimalwert bis zum Maximalwert im Bereich und machen Sie sie zu einem festgelegten Typ Konvertiert zu. Die Operation wurde für alle Tore durchgeführt, und der Produktsatz wurde für alle Sätze genommen.

Betrachten Sie die Ursache von TLE. Da die maximale Anzahl von ID-Karten, die ein Tor öffnen können, $ {10 ^ {5}} $ beträgt, werden $ {10 ^ {5}} $ Daten jedes Mal in einen Satz konvertiert und M (maximal) Sie können sehen, dass dies für das Gate $ {10 ^ {5}} $) sehr rechenintensiv ist. Da die Arbeit M-mal erledigt ist, habe ich geschätzt, dass sie im schlimmsten Fall etwa $ {O (NM)} $ kosten würde. Aufgrund der Einschränkung wurde der Berechnungsbetrag zu TLE bei $ {O (10 ^ {10})} $.

Ich werde den Python-Code als Referenz setzen.

python


n, m = map(int, input().split())
line = set(range(1, n + 1))

for i in range(m):
    l, r = map(int, input().split())
    line &= set(range(l, r + 1))

print(len(line))

Überarbeitete Richtlinie 1 Richtlinie 2

Wenn ein Satz in Betracht gezogen wird, kann er in Situationen wirksam sein, in denen die ID-Karten nicht durchgehend sind, aber in diesem Fall war der Rechenaufwand groß und er war nicht wirksam. Sie können sehen, dass der Berechnungsbetrag höchstens $ {O (N)} $ betragen sollte.

Wenn Sie erneut über die Richtlinie nachdenken, sind die Daten fortlaufend. Wenn Sie also die Nummer des größten Personalausweises unter dem Mindestwert Li des Personalausweises und der kleinsten Nummer des Maximalwerts Ri speichern, ist die Anzahl zwischen ihnen dieselbe. Ich dachte es wäre die Nummer.

Ich erkannte, dass der Hintergrund dieser Richtlinie darin bestand, die Nummern auf dem Personalausweis anzuordnen, der die Tore für jedes Tor öffnet. In diesem Fall werden ID-Karten fortlaufend eingegeben, sodass diese Methode in Ordnung ist. Ri - Li + Kann mit einem Personalausweis geöffnet werden.

Wenn sich die ID-Kartenbereiche jedoch nicht überlappen, ist der Wert von Ri - Li + 1 als Einschränkung negativ. Wenn er negativ ist, gibt es keine ID-Karte, die die Bedingung erfüllt. Implementieren Sie ihn daher, um 0 auszugeben. Muss sein.

python


n, m = map(int, input().split())
l_max = 1
r_min = 10 ** 5

for i in range(m):
    l, r = map(int, input().split())
    l_max = max(l, l_max)
    r_min = min(r, r_min)

print(max(0, r_min - l_max + 1))

Ich konnte mit diesem Code eine Klimaanlage bekommen. Ich bin damit zufrieden, wenn ich nur AC nehme, aber als ich mir die Kommentarsendung ansah, gab es einen Kommentar, der besagte, dass sie durch die imos-Methode gelöst wurde, also wurde ich interessiert und überlegte eine andere Lösung.

Richtlinie 3 vor Eingabe der imos-Methode

Bevor ich an der imos-Methode arbeite, möchte ich eine Methode betrachten, die der imos-Methode ähnlich ist. Abschließend denke ich, dass diese Methode viel Berechnung erfordert und zu TLE führt. Unsere imos-Methode löst dieses Problem.

Lassen Sie uns unsere Gedanken organisieren. In Anbetracht der Anzahl der Tore, die ID-Karten öffnen können, beträgt die Anzahl der ID-Karten, die alle Tore öffnen können, M, da jedes Tor geöffnet werden kann. Wenn es kleiner als M ist, können einige Tore nicht geöffnet werden. Mit anderen Worten, Sie können die Anzahl der ID-Karten zählen, die M Tore öffnen können.

Dann möchte ich es umsetzen. Bereiten Sie zunächst ein Array vor, um zu speichern, wie viele Tore die ID-Kartennummer öffnen kann. Ich habe ein Array namens cardid_2_num_map vorbereitet. Die Anzahl der Elemente ist eins mehr als der Maximalwert des Personalausweises. Die eingegebene Zahl ist 1 oder mehr und N oder weniger, daher habe ich versucht, den Fehler zu reduzieren, indem ich ihn so verwende, wie er bei der Angabe des Index ist. Das 0. Array wird niemals verwendet.

Wenn Sie ein Array betrachten, dessen Karten-ID-Nummer ein Index von 0 bis $ {10 ^ 5} $ ist und dessen Inhalt die Anzahl der Tore enthält, die die ID-Karte öffnen kann, [0, 1, 2, 2, 1 , 0, ...] ist das Array, das Sie im Fall des Eingabebeispiels erhalten möchten.

In Anbetracht dessen, dass für dupliziert wird, scheint der Rechenaufwand groß zu sein. Die maximale Reihenfolge der Berechnungsmenge beträgt $ {O (NM)} $ und ist TLE wie bei Betrachtung des Produktsatzes. Die imos-Methode löst dieses Problem. Wir werden es im nächsten Abschnitt diskutieren.

python


n, m = map(int, input().split())
cardid_2_num_map = [0] * (10**5 + 1)

for i in range(m):
    l, r = map(int, input().split())
    for j in range(l, r + 1):
        cardid_2_num_map[j] += 1

max_sum_num = max(cardid_2_num_map)
count_max_card = cardid_2_num_map.count(max_sum_num)

if max_sum_num == m:
    print(count_max_card)
else:
    print(0)

Imos-Methode, diesmal die führende Rolle, Politik 4

Ich werde den Artikel veröffentlichen, den ich als Referenz verwendet habe.

Imos Labor-Imos Labor Die imos-Methode ist ein Algorithmus, mit dem es gelungen ist, den Rechenaufwand zu reduzieren, indem die kumulative Summe verwendet wurde, um die Anzahl der Vorkommen aufeinanderfolgender Zahlen zu zählen und die Verarbeitung zu erfassen, die jedes Mal zu einer gezählt wurde.

Kehren wir zum obigen Problem zurück und denken darüber nach. Ich zählte die Anzahl der ID-Karten, die das Tor öffnen konnten, und aktualisierte die Werte im Array. Die maximale Reihenfolge des Berechnungsbetrags ist $ {O (NM)} $, was TLE ist. Es scheint, dass es gelöst werden kann, wenn die Reihenfolge auf ungefähr $ {O (M)} $ unterdrückt werden kann.

Wenn Sie also zum Eingabebeispiel zurückkehren, gibt es vier ID-Karten, die mit 1, 2, 3 bzw. 4 nummeriert sind. Es gibt 3 Tore, das 1. Tor kann mit 1, 2 und 3 ID-Karten geöffnet werden und das 2. Tor kann mit 2, 3 und 4 ID-Karten geöffnet werden.

Ähnlich wie in Richtlinie 3 lautet die Karten-ID-Nummer im Index 0, 1, 2, 3, 4, ..., $ {10 ^ 5} $, und der Inhalt des Arrays ist die Nummer, mit der die ID-Karte das Tor öffnen kann. Wenn Sie das beibehaltene Array betrachten, ist die Sequenz [0, 1, 2, 2, 1, 0, ...] die Sequenz, die Sie im Fall des Eingabebeispiels erhalten möchten. Der 0. Index wird nicht verwendet, da die Karten-ID 0 anzeigt. Die imos-Methode wird verwendet, um ein solches Array zu erhalten.

Initialisieren Sie zunächst das Array mit $ {10 ^ 5 + 2} $ Elementen und einem Wert von 0. Die Absicht von +2 wird später erklärt. Das erste Tor kann mit 1, 2 und 3 Karten geöffnet werden, sodass die Indexnummer 1 +1 und die Indexnummer 4 -1 ist. [0, 1, 0, 0, -1, 0, ..., 0] In ähnlicher Weise kann das zweite Tor mit 2, 3 und 4 ID-Karten geöffnet werden, sodass die Indexnummer 2 +1 und die Indexnummer 5 -1 ist. [0, 1, 1, 0, -1, -1, ..., 0] Da -1 für den Index +1 am rechten Ende des Personalausweises verwendet wird, wird die Anzahl der Elemente im Array um 1 zu $ {10 ^ 5} $ und +2 addiert (+1 wurde durchgeführt, um der Indexnummer und der Eingabe zu entsprechen. ).

Als nächstes wird die kumulative Summe dieses Arrays vom Index 0 bis zum Ende genommen. A[i + 1] = A[i] + A[i + 1] halten. Infolgedessen kann die gewünschte Sequenz [0, 1, 2, 2, 1, 0, ...] wie in Richtlinie 3 erhalten werden.

Wenn dann der Maximalwert des Arrays gleich der Anzahl der Gates ist, gibt es ID-Karten, die alle Gates öffnen können, und die Anzahl der ID-Karten mit dem Maximalwert wird gezählt. Die maximale Reihenfolge des Berechnungsbetrags betrug ungefähr $ {O (M)} $, und ich konnte AC.

python


n, m = map(int, input().split())
cardid_2_num_map = [0] * (10**5 + 2)

for i in range(m):
    l, r = map(int, input().split())
    cardid_2_num_map[l] += 1
    cardid_2_num_map[r + 1] -= 1

for i in range(1, n + 1):
    cardid_2_num_map[i] += cardid_2_num_map[i - 1]

max_sum_num = max(cardid_2_num_map)
count_max_card = cardid_2_num_map.count(max_sum_num)

if max_sum_num == m:
    print(count_max_card)
else:
    print(0)

Erwägung

Durch Hinzufügen von +1 zum Index am linken Ende des Bereichs, den Sie zählen möchten, und -1 zum Index am rechten Ende von +1 ist es möglich, +1 nur vom linken zum rechten Ende zu addieren, wenn die kumulative Summe endgültig genommen wird, und für alle Bereiche. Sie können die Anzahl der Auftritte gleichzeitig zählen.

x <Tun Sie nichts ganz links Linkes Ende <= x <= Bereich des rechten Endes wird um +1 erhöht Da der Bereich des rechten Endes <x nichts tut

Wir sind in der Lage, die beabsichtigte Zählung durchzuführen.

Diese Denkweise kann auf mehrere Dimensionen angewendet werden und der Rechenaufwand kann reduziert werden, daher fand ich sie sehr interessant. Die Abbildungen in dem Artikel, auf den ich mich bezog, waren sehr leicht zu verstehen. Das ist alles.

Recommended Posts

4 Methoden zum Zählen der Anzahl von Ganzzahlen in einem bestimmten Intervall (einschließlich der imos-Methode) [Python-Implementierung]
So zählen Sie die Anzahl der Vorkommen jedes Elements in der Liste in Python mit der Gewichtung
So zählen Sie die Anzahl der Elemente in Django und geben sie in die Vorlage aus
So ermitteln Sie die Anzahl der Stellen in Python
Ein Memorandum über die Umsetzung von Empfehlungen in Python
Wie identifiziere ich das Element mit der geringsten Anzahl von Zeichen in einer Python-Liste?
Eine einfache Python-Implementierung der k-Neighborhood-Methode (k-NN)
Verwendung der Methode __call__ in der Python-Klasse
Beispiel für die Antwort auf den Python-Code --1.2 Zählen Sie die Anzahl der gleichen Zeichen
Holen Sie sich die Anzahl der spezifischen Elemente in der Python-Liste
[Homologie] Zählen Sie mit Python die Anzahl der Löcher in den Daten
[Python] Programmieren, um die Nummer von a in einer Zeichenfolge zu finden, die eine bestimmte Anzahl von Malen wiederholt.
Wie kann man schnell die Häufigkeit des Auftretens von Zeichen aus einer Zeichenfolge in Python zählen?
Zählen Sie die Anzahl der thailändischen und arabischen Zeichen in Python gut
So bestimmen Sie die Existenz eines Selenelements in Python
So überprüfen Sie die Speichergröße einer Variablen in Python
So überprüfen Sie die Speichergröße eines Wörterbuchs in Python
Eine Funktion, die die Verarbeitungszeit einer Methode in Python misst
Holen Sie sich die Anzahl der Leser von Artikeln über Mendeley in Python
Schlafverarbeitung für einen bestimmten Zeitraum (Sekunden) oder länger in Python
Zählen / überprüfen Sie die Anzahl der Methodenaufrufe.
[Python] Ein Programm, das die Anzahl der gepaarten Socken berechnet
[Python] So fügen Sie eine beliebige Anzahl von Standardeingaben in die Liste ein
Verschiedene Methoden zum numerischen Erstellen der Umkehrfunktion einer bestimmten Funktion Einführung
Überprüfen Sie die speicherinterne Byte-Zeichenfolge der Gleitkommazahl in Python
Ich habe ein Programm erstellt, um die Größe einer Datei mit Python zu überprüfen
Zählen Sie, wie oft zwei Werte gleichzeitig in einem Element vom Typ Python 3-Iterator angezeigt werden
Verschiedene Möglichkeiten, die letzte Zeile einer CSV-Datei in Python zu lesen
So übergeben Sie das Ergebnis der Ausführung eines Shell-Befehls in einer Liste in Python
Geben Sie die Anzahl der CPU-Kerne in Python aus
Holen Sie sich den Aufrufer einer Funktion in Python
Dynamisches Ersetzen der nächsten Methode in Python
Finden Sie die Anzahl der Tage in einem Monat
Erstellen Sie eine Python-Umgebung, um die Theorie und Implementierung von Deep Learning zu erlernen
Ermitteln Sie mithilfe der Twitter-API die Anzahl der Tweets, die sich auf ein bestimmtes Keyword beziehen
Ausgabe in Form eines Python-Arrays
So erhalten Sie mit Python eine Liste der Dateien im selben Verzeichnis
Verschiedene Methoden zum numerischen Erstellen der Umkehrfunktion einer bestimmten Funktion Teil 1 Polynomregression
[Python] Ein Programm, das die kürzeste Anzahl von Schritten in einem Spiel findet, das Wolken überquert
So überprüfen Sie in Python, ob sich eines der Elemente einer Liste in einer anderen Liste befindet
[Python] Darstellung der Anzahl der Beschwerden von Lebensversicherungsunternehmen in einem Balkendiagramm
Suchen Sie eine Richtlinie für die Anzahl der Prozesse / Threads, die auf dem Anwendungsserver festgelegt werden sollen
Eine Geschichte über den Versuch, Linter mitten in einem Python (Flask) -Projekt vorzustellen
Überprüfen Sie, ob die Zeichenfolge eine Zahl in Python ist
[Python] Ein Programm, das die Anzahl der Täler zählt
Zählen Sie die Anzahl der Parameter im Deep-Learning-Modell
Python-Implementierung der Bayes'schen linearen Regressionsklasse
Ermitteln Sie die Größe (Anzahl der Elemente) von Union Find in Python
[Python] Erstellt eine Methode zum Konvertieren von Radix in 1 Sekunde
Um das Äquivalent von Rubys ObjectSpace._id2ref in Python zu tun
Python Hinweis: Das Rätsel, einer Variablen eine Variable zuzuweisen
Mal sehen, wie man die Anzahl der Elemente in einem Array in einigen Sprachen zählt [Go, JavaScript, PHP, Python, Ruby, Swift]
Ruft den Wert eines bestimmten Schlüssels bis zum angegebenen Index der Wörterbuchliste in Python ab
[Python] So löschen Sie eine Zeile / Spalte in einer Tabelle (Liste der Optionen für die Drop-Methode)
Verstehen Sie die Metropolitan Hasting-Methode (eine der Methoden in der Markov-Ketten-Monte-Carlo-Methode) mit der Implementierung
[OCI] Python-Skript zum Abrufen der IP-Adresse einer Recheninstanz in Cloud Shell
[Super einfach! ] So zeigen Sie den Inhalt von Wörterbüchern und Listen einschließlich Japanisch in Python an
Was scheint eine Vorlage für den Standardeingabe-Teil des Competition Pro in Python3 zu sein