[主席树]SPOJ DQUERY

题目链接

题意:n个数 m个查询

查询的是[l, r]区间内不相同的数的个数

 

没有修改,因此静态的主席树就好了

将重复的元素建树即可

query的时候加起来,用区间长度(r-l+1)去减就是答案

(query的是[l, r]之间重复元素的个数)

 

  1 typedef long long LL;
  2 #define lson l, m
  3 #define rson m+1, r
  4 const int N=30005;
  5 int L[N<<5], R[N<<5], sum[N<<5];
  6 int tot;
  7 int a[N], T[N];
  8 int read()
  9 {
 10     char ch=' ';
 11     int ans=0;
 12     while(ch<'0' || ch>'9')
 13         ch=getchar();
 14     while(ch<='9' && ch>='0')
 15     {
 16         ans=ans*10+ch-'0';
 17         ch=getchar();
 18     }
 19     return ans;
 20 }
 21 
 22 int build(int l, int r)
 23 {
 24     int rt=(++tot);
 25     sum[rt]=0;
 26     if(l<r)
 27     {
 28         int m=(l+r)>>1;
 29         L[rt]=build(lson);
 30         R[rt]=build(rson);
 31     }
 32     return rt;
 33 }
 34 
 35 int update(int pre, int l, int r, int x)
 36 {
 37     int rt=(++tot);
 38     L[rt]=L[pre], R[rt]=R[pre], sum[rt]=sum[pre]+1;
 39     if(l<r)
 40     {
 41         int m=(l+r)>>1;
 42         if(x<=m)
 43             L[rt]=update(L[pre], lson, x);
 44         else
 45             R[rt]=update(R[pre], rson, x);
 46     }
 47     return rt;
 48 }
 49 
 50 int query(int u, int v, int l, int r, int k)
 51 {
 52      if(l>=k)
 53         return sum[v]-sum[u];
 54     int m=(l+r)>>1;
 55     int ans=0;
 56     if(m>=k)
 57         ans+=query(L[u], L[v], lson, k);
 58     ans+=query(R[u], R[v], rson, k);
 59     return ans;
 60 }
 61 
 62 int main()
 63 {
 64         tot=0;
 65         int n=read();
 66 //        scanf("%d", &n);
 67         for(int i=1; i<=n; i++)
 68         {
 69 //            scanf("%d", &a[i]);
 70             a[i]=read();
 71         }
 72         T[0]=0;
 73         map<int, int> mp;
 74         mp.clear();
 75         for(int i=1; i<=n; i++)
 76         {
 77             if(mp.find(a[i])!=mp.end())
 78                 T[i]=update(T[i-1], 1, n, mp[a[i]]);
 79             else
 80                 T[i]=T[i-1];
 81             mp[a[i]]=i;
 82         }
 83         int m=read();
 84 //        scanf("%d", &m);
 85         while(m--)
 86         {
 87             int l, r;
 88             l=read(), r=read();
 89 //            scanf("%d%d", &l, &r);
 90             printf("%d\n", r-l+1-query(T[l-1], T[r], 1, n, l));
 91         }
 92 }
 93 /*
 94 5
 95 1 1 2 1 3
 96 3
 97 1 5
 98 2 4
 99 3 5
100 */
SPOJ DQUERY

 

posted @ 2015-07-25 10:14  Empress  阅读(...)  评论(...编辑  收藏