Submission #1280025

#TimeUsernameProblemLanguageResultExecution timeMemory
1280025SSKMFExamination (JOI19_examination)C++20
100 / 100
1211 ms89320 KiB
#include <bits/stdc++.h> using namespace std; mt19937_64 generator(72837923749);//(chrono::steady_clock::now().time_since_epoch().count()); struct Nod { uint64_t prioritate = generator(); int cantitate = 0 , valoare = 0; Nod *stanga = NULL , *dreapta = NULL; } *arbore[200000]; struct Intrebare { int limita_1 , limita_2 , limita_3 , indice; } intrebare[100001]; pair <int , int> sir[100001] , copie[100001]; int rezultat[100001] , temporar[100001]; inline int __size (Nod* &nod) { return nod ? nod -> cantitate : 0; } inline void RotateLeft (Nod* &nod) { Nod *inlocuitor = nod -> stanga; nod -> stanga = inlocuitor -> dreapta; inlocuitor -> dreapta = nod; nod -> cantitate = 1 + __size(nod -> stanga) + __size(nod -> dreapta); nod = inlocuitor; nod -> cantitate = 1 + __size(nod -> stanga) + __size(nod -> dreapta); } inline void RotateRight (Nod* &nod) { Nod *inlocuitor = nod -> dreapta; nod -> dreapta = inlocuitor -> stanga; inlocuitor -> stanga = nod; nod -> cantitate = 1 + __size(nod -> stanga) + __size(nod -> dreapta); nod = inlocuitor; nod -> cantitate = 1 + __size(nod -> stanga) + __size(nod -> dreapta); } inline void Insert (Nod* &nod , const int valoare) { if (nod == NULL) { nod = new Nod(); nod -> valoare = valoare; nod -> cantitate = 1; return; } nod -> cantitate++; if (valoare < nod -> valoare) { Insert(nod -> stanga , valoare); if (nod -> stanga -> prioritate > nod -> prioritate) { RotateLeft(nod); } } else { Insert(nod -> dreapta , valoare); if (nod -> dreapta -> prioritate > nod -> prioritate) { RotateRight(nod); } } } inline int Query (Nod* &nod , const int valoare) { if (nod == NULL) { return 0; } if (nod -> valoare < valoare) { return Query(nod -> dreapta , valoare); } return 1 + __size(nod -> dreapta) + Query(nod -> stanga , valoare); } inline void Update (const int nod , const int stanga , const int dreapta , const int indice , const int valoare) { Insert(arbore[nod] , valoare); if (stanga == dreapta) { return; } const int mijloc = (stanga + dreapta) >> 1; if (indice <= mijloc) { Update(nod + 1 , stanga , mijloc , indice , valoare); } else { Update(nod + ((mijloc - stanga + 1) << 1) , mijloc + 1 , dreapta , indice , valoare); } } inline int Query (const int nod , const int stanga , const int dreapta , const int indice , const int valoare) { if (dreapta < indice) { return 0; } if (stanga >= indice) { return Query(arbore[nod] , valoare); } const int mijloc = (stanga + dreapta) >> 1; return Query(nod + 1 , stanga , mijloc , indice , valoare) + Query(nod + ((mijloc - stanga + 1) << 1) , mijloc + 1 , dreapta , indice , valoare); } int main () { ios :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int lungime , numar_intrebari; cin >> lungime >> numar_intrebari; for (int indice = 1 ; indice <= lungime ; indice++) { cin >> sir[indice].first >> sir[indice].second; } sort(sir + 1 , sir + lungime + 1 , [] (pair <int , int>& optiune_1 , pair <int , int>& optiune_2) -> bool { return optiune_1.first + optiune_1.second > optiune_2.first + optiune_2.second; }); for (int indice = 1 ; indice <= lungime ; indice++) { copie[indice] = {sir[indice].first , indice}; } sort(copie + 1 , copie + lungime + 1); for (int indice = 1 ; indice <= lungime ; indice++) { sir[copie[indice].second].first = indice; } for (int indice = 1 ; indice <= numar_intrebari ; indice++) { cin >> intrebare[indice].limita_1 >> intrebare[indice].limita_2 >> intrebare[indice].limita_3; intrebare[indice].indice = indice; } sort(intrebare + 1 , intrebare + numar_intrebari + 1 , [] (Intrebare& optiune_1 , Intrebare& optiune_2) -> bool { return optiune_1.limita_3 > optiune_2.limita_3; }); for (int indice = 1 , __indice = 1 ; indice <= numar_intrebari ; indice++) { while (__indice <= lungime && intrebare[indice].limita_3 <= copie[sir[__indice].first].first + sir[__indice].second) { Update(1 , 1 , lungime , sir[__indice].first , sir[__indice].second); __indice++; } int stanga = 1 , dreapta = lungime; while (stanga <= dreapta) { const int mijloc = (stanga + dreapta) >> 1; if (copie[mijloc].first >= intrebare[indice].limita_1) { dreapta = mijloc - 1; } else { stanga = mijloc + 1; } } rezultat[intrebare[indice].indice] = Query(1 , 1 , lungime , stanga , intrebare[indice].limita_2); } for (int indice = 1 ; indice <= numar_intrebari ; indice++) { cout << rezultat[indice] << '\n'; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...