DQUERY - D-query
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
题意: 给你一个序列 然后q 次询问,每次输出从l到r 总共有多少不同的数。
思路: 主席树。 我们建立一个n 个节点的空的主席树 然后对数组a 逐渐插入到主席树树中去吗,那么如果当前值已经出现过,那么我们在扩展树的过程中 就先将他的出现的前一个位置的-1 然后再对该位置加一 操作。 如果当前值没有出现过 那么就更容易了,我们只需要将当前位置+1 就可以, 每次询问就只需要找当前位置的主席树中的l 右边有多少位置被标记过就可以了。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=30010;
int n,q,tot;
int a[maxn];
int T[maxn];
const int M=maxn*40;
int lson[M],rson[M],c[M];
int build(int l,int r)
{
int root=tot++;
c[tot]=0;
if(l==r){
return tot;
}
int mid=(l+r)>>1;
lson[root]=build(l,mid);
rson[root]=build(mid+1,r);
return root;
}
int update(int root,int pos,int val)
{
int newroot=tot++; int tmp=newroot;
int l=1,r=n;
// printf(" val : %d pos : %d \n",val,pos);
while(l<r)
{
int mid=(l+r)>>1;
if(pos<=mid){
// printf("left\n");
lson[newroot]=tot++; rson[newroot]=rson[root];
newroot=lson[newroot]; root=lson[root];
r=mid;
}
else{
// printf("right\n");
rson[newroot]=tot++; lson[newroot]=lson[root];
newroot=rson[newroot]; root=rson[root];
l=mid+1;
}
c[newroot]=c[root]+val;
}
return tmp;
}
int query(int root,int pos,int l,int r)
{
if(l==r) return c[root];
int mid=(l+r)>>1;
if(pos<=mid){
return c[rson[root]]+query(lson[root],pos,l,mid);
}
else{
return query(rson[root],pos,mid+1,r);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
map<int ,int >mp;
T[0]=build(1,n);
for(int i=1;i<=n;i++){
if(mp[a[i]]==0){
T[i]=update(T[i-1],i,1);
}
else{
int tmp=update(T[i-1],mp[a[i]],-1);
T[i]=update(tmp,i,1);
}
mp[a[i]]=i;
}
scanf("%d",&q);
int l,r;
for(int i=1;i<=q;i++){
scanf("%d %d",&l,&r);
int ans=query(T[r],l,1,n);
printf("%d\n",ans);
}
return 0;
}