/* Cautare binara - O(logn)
Cum cautam un element intr-un vector sortat crescator/descrescator?
1. Cea mai mica pozitie unde am un element mai mare sau egal cu x.
Exemplu: 0 1 2 3 4 5 6 7
-1 2 3 4 7 7 7 9
Daca x = 4 => poz = 3
Daca x = 6 => poz = 4
Solutie:
int poz = upper_bound(v.begin(), v.end(), valoare) - v.begin();
-returneaza un iterator catre primul element mai mare
decat valoare (adica cauta v[i] > valoare, i minim). Eu nu vreau > ci >=, asa ca nu il caut pe
x, ci pe x - 1 (adic v[i] > x -1, care cuprinde v[i] >= x).
- am zis ca am deja un iterator catre elementul gasit (e ca si cum as avea un j). Ca sa obtin
pozitia scad interatorul catre primul element ( e ca si cum as face poz = j - i).
2. Cea mai mare pozitie pe care se afla un element cu valoarea mai mica sau egala cu x in sir.
Exemplu: 0 1 2 3 4 5 6 7
-1 2 3 4 7 7 7 9
Daca x = 4 => poz = 3
Daca x = 6 => poz = 3
Solutie:
lower_bound(v.begin(), v.end(), x+1) - v.begin() - 1;
Analog 1) doar ca aici parametrul este x+1 si din pozitie scad 1. Lower cauta v[i] > x, i maxim, de aia pun x+1 si scad 1.
Daca vreau sa gasesc pe x (pozitia pe care se afla x; daca x apare de mai multe ori, nu ma intereseaza pe care il gasesc)
atunci pot folosi oricare din cele 2 metode + verificare ca v[poz] == x
*/
#include <fstream>
#include <algorithm> // pentru f
#include <vector>
#define nmax 100099
using namespace std;
ifstream f("cautbin.in");
ofstream g("cautbin.out");
int n, m, poz;
vector<int> v;
//cea mai mare pozitie pe care se afla un element cu valoarea x
//sau -1 daca aceasta valoare nu se gaseste in sir
int cb(vector<int>& v, const int& x) {
int poz = upper_bound(v.begin(), v.end(), x-1) - v.begin();
// int poz = lower_bound(v.begin(), v.end(), x+1) - v.begin() - 1; // merge si asta
// verific daca functia de cautare mi-a gasit elementul dorit
if(poz >= 0 && poz < (int)v.size() && v[poz] == x) {
return poz; // da, elementul exista
}
return -1;
}
//cea mai mare pozitie pe care se afla un element cu valoarea
//mai mica sau egala cu x in sir.
int cb_down(vector<int>& v, const int& x){
int poz = lower_bound(v.begin(), v.end(), x+1) - v.begin() - 1;
// verific daca functia de cautare mi-a gasit elementul dorit
if(poz >= 0 && poz < v.size() && v[poz] <= x) {
return poz; // da, elementul exista
}
return -1;
}
//cea mai mica pozitie pe care se afla un element cu valoarea
//mai mare sau egala cu x in sir.
int cb_up(vector<int>& v, const int& x) {
int poz = upper_bound(v.begin(), v.end(), x-1) - v.begin();
// verific daca functia de cautare mi-a gasit elementul dorit
if(poz >= 0 && poz < v.size() && v[poz] >= x) {
return poz; // da, elementul exista
}
return -1;
}
int main() {
f >> n;
for(int i = 1; i <= n; ++i) {
int x;
f >> x;
v.push_back(x);
}
f >> m;
for(int i = 1; i <= m; ++i) {
int tip, x;
f >> tip >> x;
if(!tip) {
poz = cb(v, x);
if (poz != -1) g << poz+1 << '\n';
else g << -1 << '\n';
}
if(tip == 1) {
poz = cb_down(v, x);
if (poz != -1) g << poz+1 << '\n';
else g << -1 << '\n';
}
if(tip == 2) {
poz = cb_up(v, x);
if (poz != -1) g << poz+1 << '\n';
else g << -1 << '\n';
}
}
f.close();g.close();
return 0;
}