Cod sursa(job #218346)

Utilizator plastikDan George Filimon plastik Data 1 noiembrie 2008 17:21:07
Problema Distincte Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.12 kb
// http://infoarena.ro/problema/distincte

#include <cstdio>

#include <vector>
#include <algorithm>
using namespace std;

const int TREEMAX = 1 << 18;
const int NMAX = 100000;
const int MOD = 666013;

int Tree[TREEMAX], A[NMAX];
bool Found[NMAX];
int n, m, k;
vector<pair< pair<int, int>, int > > Queries;
vector<pair<int, int> > Ans;

inline int left(int i) {
	return 2 * i;
}
inline int right(int i) {
	return 2 * i + 1;
}

void treeBuild(int i, int l, int r) {
	if (l == r) {
		Tree[i] = A[l - 1];
		return;
	}
	
	int m = (r - l) / 2 + l;
	treeBuild(left(i), l, m);
	treeBuild(right(i), m + 1, r);
	
	Tree[i] = (Tree[left(i)] + Tree[right(i)]) % MOD;
}

void treeUpdate(int pos, int key, int i, int l, int r) {
	if (l == r && l == pos) {
		Tree[i] = key;
		return;
	}
	
	int m = (r - l) / 2 + l;
	if (pos <= m)
		treeUpdate(pos, key, left(i), l, m);
	else
		treeUpdate(pos, key, right(i), m + 1, r);
	
	Tree[i] = (Tree[left(i)] + Tree[right(i)]) % MOD;
}

int treeQuery(int wl, int wr, int i, int l, int r) {
	if (wl <= l && r <= wr)
		return Tree[i];
	
	int m = (r - l) / 2 + l, lv, rv;
	lv = rv = 0;
	if (wl <= m)
		lv = treeQuery(wl, wr, left(i), l, m);
	if (m < wr)
		rv = treeQuery(wl, wr, right(i), m + 1, r);
	
	return (lv + rv) % MOD;
}

int main() {
	
	freopen("distincte.in", "r", stdin);
	freopen("distincte.out", "w", stdout);
	
	scanf("%d %d %d", &n, &k, &m);
	int i;
	for (i = 0; i < n; ++ i)
		scanf("%d", &A[i]);
	
	treeBuild(1, 1, n);
	
	int x, y;
	for (i = 0; i < m; ++ i) {
		scanf("%d %d", &x, &y);
		Queries.push_back(make_pair(make_pair(y, x), i));
	}
	sort(Queries.begin(), Queries.end());
	
	int j, prev = -1;
	for (i = 0; i < m; ++ i) {
		memset(Found, false, sizeof(Found));
		x = Queries[i].first.second, y = Queries[i].first.first;
		for (j = y - 1; j >= max(prev, x - 1); -- j)
			if (Found[A[j]] == false)
				Found[A[j]] = true;
			else {
				A[j] = 0;
				treeUpdate(j + 1, 0, 1, 1, n);
			}
		//printf("%d\n", treeQuery(x, y, 1, 1, n));
		Ans.push_back(make_pair(Queries[i].second, treeQuery(x, y, 1, 1, n)));
		
		prev = y;
	}
	sort(Ans.begin(), Ans.end());
	
	for (i = 0; i < m; ++ i)
		printf("%d\n", Ans[i].second);
	
	return 0;
}