Repeating Substring – Omówienie zadania – Hashe

Szczegółowe omówienie zadania Repeating Substring:

Link do powyższego omówienia zadania Repeating Substring: https://youtu.be/dfpERcmogNM?t=1504
Link do treści zadania Repeating Substring: https://cses.fi/problemset/task/2106/

Zadanie Repeating Substring wykorzystuje pokazuje czym są hashe: https://youtu.be/WZojS2DHEK0?t=1623
Gdzie wykorzystuje się hashe? https://youtu.be/WZojS2DHEK0?t=164

Jak się uczyć na podstawie tego zadania? https://youtu.be/QgLyXYmFQeU?t=2019
Pamiętaj by zajrzeć max 1 raz – wtedy się rozwijasz: https://youtu.be/pkLXuuOe_qA?t=3625

Lista zadań z rozwiązaniami: https://oki.org.pl/lista-zadan-materialy.php
Samouczek – przygotowanie do Olimpiad: https://oki.org.pl/tutorial/

Zajęcia Olimpiada Informatyczna POZIOM II: https://oki.org.pl/olimpiada-informatyczna-poziom-ii/
Wszystkie zajęcia: https://oki.org.pl/harmonogram-zajec/
Informacje o zajęciach: https://oki.org.pl/newsletter.php


Kod C++ programu "Repeating Substring", który jest omówiony w powyższym filmie i który otrzymuje 100%


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 7;
const int P = 313;
const int MOD1 = 1e9 + 7;
const int MOD2 = 1e9 + 9;
pair<int, int> hash_pref[MAXN];
pair<int, int> pow_P[MAXN];
pair<int, int> get_hash(int l, int r, int n)
{
pair<int, int> h = {
(hash_pref[r].first - hash_pref[l - 1].first + MOD1) % MOD1,
(hash_pref[r].second - hash_pref[l - 1].second + MOD2) % MOD2};
return {((ll)h.first * pow_P[n - l].first) % MOD1,
((ll)h.second * pow_P[n - l].second) % MOD2};
}
// zwraca indeks drugiego wystąpienia słowa
// lub -1 jeżeli żadne słowo długości d nie występuje dwukrotnie
int check_length(int d, int n)
{
if (d == 0)
return 0;
set<pair<int, int>> prev_hash;
for (int i = 1; i <= n - d + 1; ++i) {
// h = H(s[i...i+d-1])
pair<int, int> h = get_hash(i, i + d - 1, n);
if (prev_hash.find(h) != prev_hash.end())
return i;
prev_hash.insert(h);
}
return -1;
}
int BS(int lo, int hi, int n)
{
while (lo < hi) {
int mid = (lo + hi + 1) / 2;
if (check_length(mid, n) == -1)
hi = mid - 1;
else
lo = mid;
}
return lo;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
string s;
cin >> s;
int n = s.size();
pow_P[0] = {1, 1};
for (int i = 1; i <= n; ++i) {
pow_P[i] = {((ll)pow_P[i - 1].first * P) % MOD1,
((ll)pow_P[i - 1].second * P) % MOD2};
}
for (int i = 0; i < n; ++i) {
hash_pref[i + 1] = {
((ll)hash_pref[i].first + (ll)pow_P[i].first * s[i]) % MOD1,
((ll)hash_pref[i].second + (ll)pow_P[i].second * s[i]) % MOD2};
}
int d = BS(0, n-1, n);
if (d == 0) {
cout << "-1\n";
} else {
int ind = check_length(d, n);
// wypisz s[ind..ind+d-1]
for (int i = ind; i < ind + d; ++i)
cout << s[i - 1];
cout << '\n';
}
return 0;
}
Kod C++ programu "Repeating Substring", który jest omówiony w powyższym filmie i który otrzymuje 100%

Nie dodano jeszcze komentarza, rozpocznij dyskusję pierwszy.

Dodaj komentarz