Algoritmul, pas cu pas
Sunt ferestre (până la ) — nu le pot enumera. Salvarea: ambele proprietăți sunt monotone în lungime — dacă e validă, atunci și e validă (mai multe elemente nu scad nici frecvența maximă, nici numărul de distincte).
Deci, pentru fiecare start , există un capăt drept minim de la care fereastra devine validă; toate ferestrele sunt valide — adică ferestre. Și nu scade când crește, deci folosesc doi pointeri.
Cerința 2 (legitime, distincte). Țin numărul de adrese distincte din fereastra curentă (cu un vector de frecvențe). Pentru fiecare extind dreapta până am distincte, adaug , apoi scot .
Cerința 1 (suspecte, o adresă de ori). Țin numărul de valori care au atins frecvența în fereastră; fereastra e suspectă cât timp acel contor e pozitiv. Aceeași glisare.
Complexitate: (fiecare pointer parcurge șirul o singură dată), cu un vector de frecvențe de dimensiune .
Soluția în C++
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("cibernetica.in");
ofstream fout("cibernetica.out");
int main() {
int C;
long long N, K;
fin >> C >> N >> K;
vector<int> a(N);
int mx = 0;
for (auto &x : a) { fin >> x; if (x > mx) mx = x; }
vector<int> freq(mx + 1, 0);
long long total = 0;
if (C == 2) { // ferestre legitime: >= K adrese distincte
int distinct = 0, r = 0;
for (int i = 0; i < N; i++) {
while (r < N && distinct < K) {
if (freq[a[r]] == 0) distinct++;
freq[a[r]]++;
r++;
}
if (distinct >= K) total += N - r + 1;
if (freq[a[i]] == 1) distinct--;
freq[a[i]]--;
}
} else { // C == 1: ferestre suspecte: o adresă cu frecvență >= K
int numK = 0, r = 0; // câte valori au atins frecvența K
for (int i = 0; i < N; i++) {
while (r < N && numK == 0) {
freq[a[r]]++;
if (freq[a[r]] == K) numK++;
r++;
}
if (numK > 0) total += N - r + 1;
if (freq[a[i]] == K) numK--;
freq[a[i]]--;
}
}
fout << total << "\n";
return 0;
}- Enumerezi toate ferestrele — înseamnă operații; folosește monotonia și doi pointeri pentru .
- Folosești
intpentru rezultat — numărul de ferestre poate ajunge la , decilong long. - Uiți să scoți din fereastră când treci la următorul start — altfel frecvențele și numărul de distincte rămân greșite.