Submission #1170253

#TimeUsernameProblemLanguageResultExecution timeMemory
1170253userro1234324Two Antennas (JOI19_antennas)C++20
0 / 100
171 ms19348 KiB
#include <bits/stdc++.h>
using namespace std;
int n, q;
int h[200001];
int a[200001];
int b[200001];
struct p {
    int pocz;
    int kon;
    int indeks;
};
p pytania[200000];
int odpowiedzi[200000];
int kolejny;
pair <int, pair<bool, int>> zmiana_stanu[400000];
bool posortuj(p a, p b) {
    return a.kon < b.kon;
}
void wczytaj() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d %d %d", &h[i], &a[i], &b[i]);
        zmiana_stanu[kolejny++] = {i + a[i], {0, i}};
        zmiana_stanu[kolejny++] = {i + b[i], {1, i}};
    }
    scanf("%d", &q);
    for (int i = 0; i < q; i++) {
        scanf("%d %d", &pytania[i].pocz, &pytania[i].kon);
        pytania[i].indeks = i;
    }
    sort(pytania, pytania + q, posortuj);
    sort(zmiana_stanu, zmiana_stanu + kolejny);
}
const int maxn = 524288;
const int baza = 262143;
const int maksymalna_wartosc = 1000000001;
int drzewo_lewe_minimum[maxn];
int drzewo_lewe_maksimum[maxn];
int drzewo_prawe_minimum[maxn];
int drzewo_prawe_maksimum[maxn];
int drzewo_lewy_minus_prawy[maxn];
int drzewo_prawy_minus_lewy[maxn];
bool drzewo_czy_nalezy_spuscic[maxn];
void przygotuj_drzewa() {
    for (int i = 1; i < maxn; i++) {
        drzewo_lewe_minimum[i] = maksymalna_wartosc;
        drzewo_lewe_maksimum[i] = -1;
        drzewo_prawe_minimum[i] = maksymalna_wartosc;
        drzewo_prawe_maksimum[i] = -1;
        drzewo_lewy_minus_prawy[i] = -1;
        drzewo_prawy_minus_lewy[i] = -1;
    }
}
void wlacz_lewa_wartosc_na_drzewach_min_max(int indeks) {
    indeks += baza;
    drzewo_lewe_minimum[indeks] = h[indeks - baza];
    drzewo_lewe_maksimum[indeks] = h[indeks - baza];
    indeks >>= 1;
    while (indeks) {
        drzewo_lewe_minimum[indeks] = min(drzewo_lewe_minimum[2 * indeks], drzewo_lewe_minimum[2 * indeks + 1]);
        drzewo_lewe_maksimum[indeks] = max(drzewo_lewe_maksimum[2 * indeks], drzewo_lewe_maksimum[2 * indeks + 1]);
        indeks >>= 1;
    }
}
void wylacz_lewa_wartosc_na_drzewach_min_max(int indeks) {
    indeks += baza;
    drzewo_lewe_minimum[indeks] = maksymalna_wartosc;
    drzewo_lewe_maksimum[indeks] = -1;
    indeks >>= 1;
    while (indeks) {
        drzewo_lewe_minimum[indeks] = min(drzewo_lewe_minimum[2 * indeks], drzewo_lewe_minimum[2 * indeks + 1]);
        drzewo_lewe_maksimum[indeks] = max(drzewo_lewe_maksimum[2 * indeks], drzewo_lewe_maksimum[2 * indeks + 1]);
        indeks >>= 1;
    }
}
void spusc_na_dol(int x) {
    int syn1 = 2 * x; int syn2 = syn1 + 1;
    drzewo_czy_nalezy_spuscic[syn1] = true;
    drzewo_czy_nalezy_spuscic[syn2] = true;
    drzewo_czy_nalezy_spuscic[x] = false;
    // syn1
    drzewo_prawe_maksimum[syn1] = max(drzewo_prawe_maksimum[syn1], drzewo_prawe_maksimum[x]);
    drzewo_prawe_minimum[syn1] = min(drzewo_prawe_minimum[syn1], drzewo_prawe_minimum[x]);
    drzewo_lewy_minus_prawy[syn1] = max(drzewo_lewy_minus_prawy[syn1], drzewo_lewe_maksimum[syn1] - drzewo_prawe_minimum[syn1]);
    drzewo_prawy_minus_lewy[syn1] = max(drzewo_prawy_minus_lewy[syn1], drzewo_prawe_maksimum[syn1] - drzewo_lewe_minimum[syn1]);
    // to samo dla syn2
    drzewo_prawe_maksimum[syn2] = max(drzewo_prawe_maksimum[syn2], drzewo_prawe_maksimum[x]);
    drzewo_prawe_minimum[syn2] = min(drzewo_prawe_minimum[syn2], drzewo_prawe_minimum[x]);
    drzewo_lewy_minus_prawy[syn2] = max(drzewo_lewy_minus_prawy[syn2], drzewo_lewe_maksimum[syn2] - drzewo_prawe_minimum[syn2]);
    drzewo_prawy_minus_lewy[syn2] = max(drzewo_prawy_minus_lewy[syn2], drzewo_prawe_maksimum[syn2] - drzewo_lewe_minimum[syn2]);
}
int szukany_pocz, szukany_kon, wartosc;
int wynik_na_przedziale(int x, int aktualny_pocz, int aktualny_kon) {
    if (aktualny_pocz > szukany_kon || aktualny_kon < szukany_pocz) return -1;
    if (aktualny_pocz >= szukany_pocz && aktualny_kon <= szukany_kon) return max(drzewo_lewy_minus_prawy[x], drzewo_prawy_minus_lewy[x]);
    if (drzewo_czy_nalezy_spuscic[x]) spusc_na_dol(x);
    int syn1 = 2 * x; int syn2 = syn1 + 1;
    int wynik1 = wynik_na_przedziale(syn1, aktualny_pocz, (aktualny_pocz + aktualny_kon) / 2);
    int wynik2 = wynik_na_przedziale(syn2, (aktualny_pocz + aktualny_kon) / 2 + 1, aktualny_kon);
    return max(wynik1, wynik2);
}
void dodaj_wartosc_na_przedziale(int x, int aktualny_pocz, int aktualny_kon) {
    if (aktualny_pocz > szukany_kon || szukany_pocz > aktualny_kon) return;
    if (aktualny_pocz >= szukany_pocz && aktualny_kon <= szukany_kon) {
        drzewo_prawe_maksimum[x] = max(drzewo_prawe_maksimum[x], wartosc);
        drzewo_prawe_minimum[x] = min(drzewo_prawe_minimum[x], wartosc);
        drzewo_lewy_minus_prawy[x] = max(drzewo_lewy_minus_prawy[x], drzewo_lewe_maksimum[x] - drzewo_prawe_minimum[x]);
        drzewo_prawy_minus_lewy[x] = max(drzewo_prawy_minus_lewy[x], drzewo_prawe_maksimum[x] - drzewo_lewe_minimum[x]);
        drzewo_czy_nalezy_spuscic[x] = true;
        return;
    }
    if (drzewo_czy_nalezy_spuscic[x]) spusc_na_dol(x);
    dodaj_wartosc_na_przedziale(2 * x, aktualny_pocz, (aktualny_pocz + aktualny_kon) / 2);
    dodaj_wartosc_na_przedziale(2 * x + 1, (aktualny_pocz + aktualny_kon) / 2 + 1, aktualny_kon);
    drzewo_prawe_maksimum[x] = min(drzewo_prawe_maksimum[2 * x], drzewo_prawe_maksimum[2 * x + 1]);
    drzewo_prawe_minimum[x] = max(drzewo_prawe_minimum[2 * x], drzewo_prawe_minimum[2 * x + 1]);
    drzewo_lewy_minus_prawy[x] = max(drzewo_lewy_minus_prawy[2 * x], drzewo_lewy_minus_prawy[2 * x + 1]);
    drzewo_prawy_minus_lewy[x] = max(drzewo_prawy_minus_lewy[2 * x], drzewo_prawy_minus_lewy[2 * x + 1]);
}
void pospuszczaj_sie_do_indeksu(int indeks) {
    int x = 1, pocz = 1, kon = baza + 1;
    while (x != indeks + baza) {
        spusc_na_dol(x);
        int srodek = (pocz + kon) / 2;
        if (indeks <= srodek) {
            x = 2 * x;
            kon = srodek;
        }
        else {
            x = 2 * x + 1;
            pocz = srodek + 1;
        }
    }
}
void wlacz_indeks(int indeks) {
    wlacz_lewa_wartosc_na_drzewach_min_max(indeks);
    pospuszczaj_sie_do_indeksu(indeks);
    indeks += baza;
    drzewo_prawe_maksimum[indeks] = -1;
    drzewo_prawe_minimum[indeks] = maksymalna_wartosc;
    indeks >>= 1;
    while (indeks) {
        drzewo_prawe_maksimum[indeks] = -1;
        drzewo_prawe_minimum[indeks] = maksymalna_wartosc;
        indeks >>= 1;
    }
}
void wylacz_indeks(int indeks) {
    wylacz_lewa_wartosc_na_drzewach_min_max(indeks);
    //pospuszczaj_sie_do_indeksu(indeks);
    //indeks += baza;
    //drzewo_prawe_maksimum[indeks] = -1;
    //drzewo_prawe_minimum[indeks] = maksymalna_wartosc;
    //indeks >>= 1;
    //while (indeks) {
        //drzewo_prawe_maksimum[indeks] = -1;
        //drzewo_prawe_minimum[indeks] = maksymalna_wartosc;
        //indeks >>= 1;
    //}
}
void zrob_zadanie() {
    int l = 0;
    int s = 0;
    for (int i = 1; i <= n; i++) {
        while (l < kolejny && zmiana_stanu[l].first == i && zmiana_stanu[l].second.first == 0) {
            wlacz_indeks(zmiana_stanu[l].second.second);
            l++;
        }
        szukany_pocz = max(i - b[i], 1);
        szukany_kon = i - a[i];
        if (szukany_pocz <= szukany_kon) {
            wartosc = h[i];
            dodaj_wartosc_na_przedziale(1, 1, baza + 1);
        }
        while (s < q && pytania[s].kon == i) {
            szukany_pocz = pytania[s].pocz;
            szukany_kon = pytania[s].kon;
            odpowiedzi[pytania[s].indeks] = wynik_na_przedziale(1, 1, baza + 1);
            s++;
        }
        while (l < kolejny && zmiana_stanu[l].first == i && zmiana_stanu[l].second.first == 1) {
            wylacz_indeks(zmiana_stanu[l].second.second);
            l++;
        }
    }
}
void wypisz_odpowiedzi() {
    for (int i = 0; i < q; i++) {
        printf("%d\n", odpowiedzi[i]);
    }
}
int main() {
    wczytaj();
    przygotuj_drzewa();
    zrob_zadanie();
    wypisz_odpowiedzi();
}

Compilation message (stderr)

antennas.cpp: In function 'void wczytaj()':
antennas.cpp:20:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   20 |     scanf("%d", &n);
      |     ~~~~~^~~~~~~~~~
antennas.cpp:22:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   22 |         scanf("%d %d %d", &h[i], &a[i], &b[i]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
antennas.cpp:26:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   26 |     scanf("%d", &q);
      |     ~~~~~^~~~~~~~~~
antennas.cpp:28:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   28 |         scanf("%d %d", &pytania[i].pocz, &pytania[i].kon);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...