D-query SPOJ - DQUERY 主席树模板题

DQUERY - D-query


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;
}

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/80285389