题目描述
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答……因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。
输入格式
第一行:一个整数N,表示项链的长度。
第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。
第三行:一个整数M,表示HH 询问的个数。
接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
输出格式
M 行,每行一个整数,依次表示询问对应的答案。
输入输出样例
输入
6
1 2 3 4 3 5
3
1 2
3 5
2 6
输出
2
2
4
说明/提示
对于20%的数据,
n
,
m
≤
5000
n
n,m\leq 5000n
n,m≤5000n
对于40%的数据,
n
,
m
≤
1
0
5
n,m\leq 10^5
n,m≤105
对于60%的数据,
n
,
m
≤
5
×
1
0
5
n,m\leq 5\times 10^5
n,m≤5×105
对于所有数据,
n
,
m
≤
1
×
1
0
6
n,m\leq 1\times 10^6
n,m≤1×106
本题可能需要较快的读入方式,最大数据点读入数据约20MB
我们考虑把询问离线下来,按右端点从小到大排序,我们从左往右扫,遇到一个新出现的数字就在数组中将其赋成一,记录其出现位置,如果这个数在之前出现了,就将之前的数组赋回零。这样我们就保证了每个数在区间内贡献为1。用树状数组维护,答案为区间前缀和,离线求出全部的答案,最后输出答案即可。
#include<bits/stdc++.h>
#define ll long long
#define MAXN 1000010
#define N 201
#define INF 0x3f3f3f3f
#define gtc() getchar()
using namespace std;
template <class T>
inline void read(T &s){
s = 0; T w = 1, ch = gtc();
while(!isdigit(ch)){if(ch == '-') w = -1; ch = gtc();}
while(isdigit(ch)){s = s * 10 + ch - '0'; ch = gtc();}
s *= w;
}
template <class T>
inline void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) write(x/10);
putchar(x % 10 + '0');
}
struct node{
int l, r, id;
}q[MAXN];
int pre[MAXN], t[MAXN], a[MAXN], ans[MAXN];
int n, m;
bool cmp(node a, node b){
return a.r < b.r;
}
inline int lowbit(int x){
return x & (-x);
}
inline void add(int x, int k){
while(x <= n){
t[x] += k;
x += lowbit(x);
}
}
inline int sum(int x){
int ans = 0;
while(x > 0){
ans += t[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
read(n);
for(int i = 1; i <= n; ++i) read(a[i]);
read(m);
for(int i = 1; i <= m; ++i) read(q[i].l), read(q[i].r), q[i].id = i;
sort(q + 1, q + m + 1, cmp);
int st = 1;
for(int i = 1; i <= m; ++i){
for(int j = st; j <= q[i].r; ++j){
add(j, 1);
if(pre[a[j]]){
add(pre[a[j]], -1);
}
pre[a[j]] = j;
}
ans[q[i].id] = sum(q[i].r) - sum(q[i].l-1);
st = q[i].r + 1;
}
for(int i = 1; i <= m; ++i) write(ans[i]), puts("");
return 0;
}