Cod sursa(job #1713058)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 4 iunie 2016 15:58:20
Problema Pq Scor 0
Compilator cpp Status done
Runda Arhiva ICPC Marime 2.33 kb
using namespace std;
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define Nmax 100010
#define Qmax 100010

struct query_t
{
	int a, b, pos;
	query_t(int _a = 0, int _b = 0, int _pos = 0) : a(_a), b(_b), pos(_pos) {}
	bool operator <(const query_t &rhs) { return a < rhs.a; }
};

int lastOcurr[Nmax], nextOcurr[Nmax], v[Nmax];
int aint[4 * Nmax];
int sol[Qmax];
vector< query_t > queries;

void Read(int&);
void BuildAint(int, int, int);
int GetMin(int, int, int, int, int);
void Delete(int, int, int, int);

int main()
{
	int i, n;
	vector< query_t >::iterator qit;

	Read(n);

	sort(queries.begin(), queries.end());
	BuildAint(1, 1, n);

	for (qit = queries.begin(), i = 1; i <= n; ++i)
	{
		for (; qit != queries.end() && qit->a == i; ++qit) sol[qit->pos] = GetMin(1, 1, n, qit->a, qit->b);

		Delete(1, 1, n, nextOcurr[i]);
	}

	ofstream fout("pq.out");

	for (i = 1; i <= queries.size(); ++i)
		fout << (sol[i] ? sol[i] : -1) << '\n';

	fout.close();

    return 0;
}

void Read(int &n)
{
	int i, q, a, b;
	ifstream fin("pq.in");

	fin >> n >> q;

	for (i = 1; i <= n; ++i)
	{
		fin >> a;

		if (lastOcurr[a]) v[i] = i - lastOcurr[a], nextOcurr[lastOcurr[a]] = i;
		lastOcurr[a] = i;
	}

	queries.reserve(q);
	for (i = 1; i <= q; ++i)
	{
		fin >> a >> b;
		queries.emplace_back(a, b, i);
	}

	fin.close();
}

void BuildAint(int node, int l, int r)
{
	if (l == r) aint[node] = v[l];
	else
	{
		int mid = (l + r) / 2;

		BuildAint(2 * node, l, mid);
		BuildAint(2 * node + 1, mid + 1, r);

		aint[node] = max(aint[2 * node], aint[2 * node + 1]);
	}
}

int GetMin(int node, int l, int r, int a, int b)
{
	if (a <= l && r <= b) return aint[node];

	int mid = (l + r) / 2, v1 = 0, v2 = 0;

	if (a <= mid) v1 = GetMin(2 * node, l, mid, a, b);
	if (mid + 1 <= b) v2 = GetMin(2 * node + 1, mid + 1, r, a, b);

	return max(v1, v2);
}

void Delete(int node, int l, int r, int pos)
{
	if (l == r) aint[node] = 0;
	else
	{
		int mid = (l + r) / 2;
		if (pos <= mid) Delete(2 * node, l, mid, pos);
		else Delete(2 * node + 1, mid + 1, r, pos);

		aint[node] = max(aint[2 * node], aint[2 * node + 1]);
	}
}