Cod sursa(job #1742433)

Utilizator whoasdas dasdas who Data 16 august 2016 14:13:42
Problema Cautare binara Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.28 kb
#define IA_PROB "cautbin"

#include <cassert>
#include <cstdio>
#include <cstring>

#include <iostream>
#include <fstream>

#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>

#include <algorithm>

using namespace std;

//FGE
int bs_first_greater_or_equal(vector<int> &v, int x, int l, int r) {
	assert(l >= 0 && r < v.size() + 1);
	while (l < r) {
		int m = l + (r - l) / 2;
		assert(m >= 0 && m < v.size()); //m points to an actual element inside the vector
		if (v[m] >= x)
			r = m;     //the m-th element qualifies, so we keep it and discard all its successors
		else
			l = m + 1; //the m-th element does not qualify, so we discard it and all its predecessors
	}
	assert(l == r);
	return l;
}

//LLE
int bs_last_lesser_or_equal(vector<int> &v, int x, int l, int r) {
//	assert(l >= -1 && r < v.size());
	while (l < r) {
		int m = l + (r - l + 1) / 2;    //+1, or else we'd never look at the last element
//		assert(m >= 0 && m < v.size()); //m points to an actual element inside the vector
		if (v[m] <= x)
			l = m;     //the m-th element qualifies, so we keep it and discard all its predecessors
		else
			r = m - 1; //the m-th element does not qualify, so we discard it and all its successors
	}
	assert(l == r);
	return l;
}


int bs_lower_bound(vector<int> &v, int x) {
	return bs_first_greater_or_equal(v, x, 0, v.size());
}
int bs_upper_bound(vector<int> &v, int x) {
	return bs_last_lesser_or_equal(v, x, -1, v.size() - 1);
}

int main()
{
	freopen(IA_PROB".in", "r", stdin);
	freopen(IA_PROB".out", "w", stdout);

	int n;
    scanf("%d", &n);
    assert(n > 0);

    vector<int> v;
    for (int i = 0; i < n; i++) {
    	int x;
    	scanf("%d", &x);
    	v.push_back(x);
    }

    int m;
    scanf("%d", &m);
    assert(m >= 0);

    for (int i = 0; i < m; i++) {
    	int op, x, ret;
    	scanf("%d %d", &op, &x);
    	switch(op) {
    	case 0:
    	case 1: {
    		int idx_lle = bs_upper_bound(v, x);
    		assert(idx_lle >= -1 && idx_lle < n);
    		if (idx_lle >= 0 && (op == 1 || v[idx_lle] == x)) ret = idx_lle + 1;
    		else ret = -1;
    		break;
    	}
    	case 2: {
    		int idx_fge = bs_lower_bound(v, x);
    		assert(idx_fge >= 0 && idx_fge < n + 1);
    		ret = idx_fge + 1;
    		break;
    	}
    	}
    	printf("%d\n", ret);
    }

    return 0;
}