Cod sursa(job #1585843)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 31 ianuarie 2016 15:35:49
Problema Distincte Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
using namespace std;

auto pi_cmp = [](const pair<int, int>& a, const pair<int, int>& b){
	return a.first < b.first || (a.first == b.first && a.second < b.second); };

class s_parter{
	int n;
	vector<pair<int, int>> pts;
	vector<int> s_part;
	void do_sums(){
		if(n == 0){
			return; }
		s_part[0] = pts[0].second;
		for(int i = 1; i < n; ++i){
			s_part[i] = s_part[i-1] + pts[i].second; } }
public:
	int size()const{
		return n; }
	s_parter(){}
	s_parter(const vector<pair<int, int>>& p): n(p.size()), pts(p), s_part(n, 0){
		do_sums(); }
	s_parter(const s_parter& lhs, const s_parter& rhs): n(lhs.pts.size() + rhs.pts.size()),
		pts(n), s_part(n, 0){
		merge(begin(lhs.pts), end(lhs.pts), begin(rhs.pts), end(rhs.pts), begin(pts), pi_cmp);
		do_sums(); }
	int query_upto(const int val)const{
		int poz = upper_bound(begin(pts), end(pts), make_pair(val, 1000000000), pi_cmp) - begin(pts);
		if(poz <= 0){
			return 0; }
		return s_part[poz-1]; } };

class arbint_2d{
	int n;
	vector<s_parter> buf;
public:
	arbint_2d(){}
	arbint_2d(const vector<pair<int, int>>& v): n(v.size()), buf(2*n){
		for(int i = 0; i < n; ++i){
			buf[i+n] = s_parter(vector<pair<int, int>>({v[i]})); }
		for(int i = n-1; i > 0; --i){
			buf[i] = s_parter(buf[2*i], buf[2*i+1]); } }
	int query(int st, int dr)const{
		int rez = 0;
		const int st_init = st;
		for(st += n, dr += n+1; st < dr; st /= 2, dr /= 2){
			if(st%2 == 1){
				rez += buf[st++].query_upto(st_init-1); }
			if(dr%2 == 1){
				rez += buf[--dr].query_upto(st_init-1); } }
		return rez; } };

int main(){
	ifstream f("distincte.in");
	ofstream g("distincte.out");

	int n, k, m;
	f >> n >> k >> m;

	arbint_2d a2d;
	{
		vector<int> v(n), prev(k, -1), v2(n);

		for(auto& x : v){
			f >> x;
			--x; }
		for(int i = 0; i < n; ++i){
			v2[i] = prev[v[i]];
			prev[v[i]] = i; }

		vector<pair<int, int>> v3(n);
		for(int i = 0; i < n; ++i){
			v3[i] = make_pair(v2[i], v[i]+1); }
		a2d = arbint_2d(v3); }

	for(int i = 0, a, b; i < m; ++i){
		f >> a >> b;
		g << a2d.query(a-1, b-1) << '\n'; }
	return 0; }