题目描述
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。
有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答…… 因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。
输入格式
一行一个正整数 nn,表示项链长度。
第二行 nn 个正整数 aiai,表示项链中第 ii 个贝壳的种类。
第三行一个整数 mm,表示 HH 询问的个数。
接下来 mm 行,每行两个整数 l,rl,r,表示询问的区间。
输出格式
输出 mm 行,每行一个整数,依次表示询问对应的答案。
输入输出样例
输入 #1复制
6 1 2 3 4 3 5 3 1 2 3 5 2 6
输出 #1复制
2 2 4
说明/提示
【数据范围】
对于 20%20% 的数据,1≤n,m≤50001≤n,m≤5000;
对于 40%40% 的数据,1≤n,m≤1051≤n,m≤105;
对于 60%60% 的数据,1≤n,m≤5×1051≤n,m≤5×105;
对于 100%100% 的数据,1≤n,m,ai≤1061≤n,m,ai≤106,1≤l≤r≤n1≤l≤r≤n。
本题可能需要较快的读入方式,最大数据点读入数据约 20MB
const int MAX=1e6;
struct node {
int l,r,k;
}q[MAX];
int pos[MAX];
int ans[MAX];
int cnt[MAX];
int a[MAX];
bool cmp(node a,node b){
if(pos[a.l]!=pos[b.l]){
return pos[a.l]<pos[b.l]; //第一标准是块的左边界
}
if(pos[a.l]&1) return a.r>b.r; //玄学的奇偶优化
return a.r<b.r;
}
int ANS=0;
void add(int x){
cnt[a[x]]++;
if(cnt[a[x]]==1) ANS++;
}
void del(int x){
cnt[a[x]]--;
if(cnt[a[x]]==0) ANS--;
}
int main(){
int n;
cin>>n;
int block=sqrt(n);
for(int i=1;i<=n;i++){
cin>>a[i];
pos[i]=(i-1)/block+1;
}
int m;
cin>>m;
for(int i=1;i<=m;i++){
cin>>q[i].l>>q[i].r;
q[i].k=i;
}
sort(q+1,q+m+1,cmp);
int l=1;
int r=0;
for(int i=1;i<=m;i++){
while(l<q[i].l) del(l++);
while(r>q[i].r) del(r--);
while(l>q[i].l) add(--l);
while(r<q[i].r) add(++r);
ans[q[i].k]=ANS;
}
for(int i=1;i<=m;i++){
cout<<ans[i]<<endl;
}
}