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
题目大意:给你一个长度为n的序列,接着M次询问,每次询问该区间有多少个不同的数。
。。。这题离线之后就可以直接用树状数组来完成,就不需要主席树了。离线之后我们将区间按右端点最小值排序。
接下来我们从1枚举到n,并将每个位置i单点更新,一旦碰到枚举变量的值为某个区间的右端点时就求和一次。但是如果在这之前a[i]已经出现过了,那么我们应该将之前出现a[i]的位置放空,然后再更新i,那么我们这样就可以保证每个数只出现一次了。而每次有重复出现元素的时候之所以可以删去前面的数是因为如果前面的位置如果属于区间x,那么后面再次出现的这个元素也一定会属于x,也就是说前面的那些重复元素是无用的,可以直接删去。
以下是AC代码:
#include <bits/stdc++.h>
using namespace std;
const int mac=3e4+10;
const int maxn=2e5+10;
int n,a[mac],b[mac],vis[mac];
int tree[mac],ans[maxn];
struct node
{
int l,r,id;
bool operator <(const node &a)const{
return r<a.r;
}
}c[maxn];
int lowbit(int x){return x&-x;}
void update(int pos,int val)
{
while (pos<=n){
tree[pos]+=val;
pos+=lowbit(pos);
}
}
int query(int l,int r)
{
int sumr=0,suml=0;
for (int i=r; i>0; i-=lowbit(i)) sumr+=tree[i];
for (int i=l-1; i>0; i-=lowbit(i)) suml+=tree[i];
return sumr-suml;
}
int main()
{
int m;
scanf ("%d",&n);
for (int i=1; i<=n; i++)
scanf ("%d",&a[i]),b[i]=a[i];
sort(b+1,b+1+n);
int numb=unique(b+1,b+1+n)-b-1;
for (int i=1; i<=n; i++)
a[i]=lower_bound(b+1,b+1+numb,a[i])-b;//其实这题的a[i]比较小不太需要离散化
scanf ("%d",&m);
for (int i=1; i<=m; i++){
int l,r;
scanf ("%d%d",&l,&r);
c[i].l=l;c[i].r=r;
c[i].id=i;
}
sort(c+1,c+1+m);
int j=1;
for (int i=1; i<=n; i++){
if (vis[a[i]]) update(vis[a[i]],-1);
update(i,1);
while (j<=m && c[j].r==i){
ans[c[j].id]=query(c[j].l,c[j].r);
j++;
}
vis[a[i]]=i;
}
for (int i=1; i<=m; i++)
printf ("%d\n",ans[i]);
return 0;
}