D-query SPOJ - DQUERY (莫队)

版权声明: https://blog.csdn.net/nucleare/article/details/88969864

D-query

 SPOJ - DQUERY 

English Vietnamese

Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.

Input

  • Line 1: n (1 ≤ n ≤ 30000).
  • Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
  • Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
  • In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).

Output

  • For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.

Example

Input
5
1 1 2 1 3
3
1 5
2 4
3 5

Output
3
2
3 

题意:求区间种类数

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 3e4 + 7;
const int M = 1e6 + 7;
int a[N];
int in[M], sum; //!标记!、种类 
int ans[200007]; //答案 
struct Q {
	int l, r, b, id; //l,r为询问区间,b为block即所属的块,id为询问的下标(先后 
	bool operator< (const Q &a) const {
		if (b == a.b) return r < a.r; //b!!!
		return b < a.b;
	}
} qq[200007];
//up and down 要根据题目要求更改 
void up(int x) {  
	if (in[a[x]] == 0) ++sum;
	++in[a[x]];
}
void down(int x) {
	--in[a[x]];
	if (in[a[x]] == 0) --sum;
}
int main() {
	int n, block;
	while (~scanf ("%d", &n)) {
		memset(in, 0, sizeof(in));
		block = sqrt(n*1.0); //分块 
		for (int i = 1; i <= n; ++i) {
			scanf ("%d", &a[i]);
		}
		int q;
		scanf ("%d", &q);
		for (int i = 1; i <= q; ++i) {
			scanf ("%d %d", &qq[i].l, &qq[i].r);
			qq[i].id = i, qq[i].b = qq[i].l / block;
		}
		sort(qq+1, qq+q+1);
		int l = 1, r = 0; //初始的区间 
		// l为什么是1,因为++r时会把l的给加了, 是0的话会重复 
		sum = 0;
		for (int i = 1; i <= q; ++i) {
			int ll = qq[i].l;
			int rr = qq[i].r;
			//扩大 
			while (r < rr) ++r, up(r);
			while (l > ll) --l, up(l);
			//缩小 
			while (r > rr) down(r), --r; //顺序 
			while (l < ll) down(l), ++l;
			//记录答案 
			ans[qq[i].id] = sum;
		}
		for (int i = 1; i <= q; ++i) {
			printf ("%d\n", ans[i]);
		}
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/nucleare/article/details/88969864