// 28-1-6: Řešení ve skutečně konstantním čase #include #include #define MAXB 1000 int K; // Jak dlouhé je okénko int n; // Kolik hodnot jsme už viděli int B; // Velikost bloku // O každém bloku si pamatujeme tyto údaje: struct blok { int x[MAXB]; // Hodnoty uvnitř bloku int n; // Kolik z nich jsme zatím viděli int pm[MAXB+1]; // Prefixová minima int sm[MAXB+1]; // Suffixová minima }; struct blok bloky[3]; // Cyklické pole bloků int aktivni; // Který blok je nejnovější struct blok *a, *m, *p; // Aktuální, minulý a předminulý blok int min; // Aktuální minimum // Inicializace nového bloku void init(void) { aktivni = (aktivni + 1) % 3; a = &bloky[aktivni]; m = &bloky[(aktivni+2) % 3]; p = &bloky[(aktivni+1) % 3]; a->n = 0; a->pm[0] = a->sm[0] = INT_MAX; } int min2(int a, int b) { return (a < b) ? a : b; } // Přidání prvku do posloupnosti void add(int x) { n++; // Přidáme do aktuálního bloku a přepočítáme prefixové minimum int i = ++a->n; a->x[i-1] = x; a->pm[i] = min2(a->pm[i-1], x); // V minulém bloku přepočítáme další suffixové minimum m->sm[i] = min2(m->sm[i-1], m->x[B-i]); // Pokud se naplnil blok, přepneme na další if (i == B) init(); // Vypočteme minimum okénka i = a->n; min = min2(a->pm[i], min2(m->pm[B], p->sm[K-B-i])); } int main(void) { scanf("%d", &K); B = (K+1) / 2; init(); init(); init(); int x; while (scanf("%d", &x) == 1) { add(x); if (n >= K) printf("%d\n", min); } return 0; }