[主席树]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 */