SPOJ 3267. D-query (主席树,查询区间有多少个不相同的数)
3267. D-queryProblem code: DQUERY |
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
主席树的入门题了
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-9-5 23:54:37 4 File Name :F:\2013ACM练习\专题学习\主席树\SPOJ_DQUERY.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 21 /* 22 * 给出一个序列,查询区间内有多少个不相同的数 23 */ 24 const int MAXN = 30010; 25 const int M = MAXN * 100; 26 int n,q,tot; 27 int a[MAXN]; 28 int T[M],lson[M],rson[M],c[M]; 29 int build(int l,int r) 30 { 31 int root = tot++; 32 c[root] = 0; 33 if(l != r) 34 { 35 int mid = (l+r)>>1; 36 lson[root] = build(l,mid); 37 rson[root] = build(mid+1,r); 38 } 39 return root; 40 } 41 int update(int root,int pos,int val) 42 { 43 int newroot = tot++, tmp = newroot; 44 c[newroot] = c[root] + val; 45 int l = 1, r = n; 46 while(l < r) 47 { 48 int mid = (l+r)>>1; 49 if(pos <= mid) 50 { 51 lson[newroot] = tot++; rson[newroot] = rson[root]; 52 newroot = lson[newroot]; root = lson[root]; 53 r = mid; 54 } 55 else 56 { 57 rson[newroot] = tot++; lson[newroot] = lson[root]; 58 newroot = rson[newroot]; root = rson[root]; 59 l = mid+1; 60 } 61 c[newroot] = c[root] + val; 62 } 63 return tmp; 64 } 65 int query(int root,int pos) 66 { 67 int ret = 0; 68 int l = 1, r = n; 69 while(pos < r) 70 { 71 int mid = (l+r)>>1; 72 if(pos <= mid) 73 { 74 r = mid; 75 root = lson[root]; 76 } 77 else 78 { 79 ret += c[lson[root]]; 80 root = rson[root]; 81 l = mid+1; 82 } 83 } 84 return ret + c[root]; 85 } 86 87 int main() 88 { 89 //freopen("in.txt","r",stdin); 90 //freopen("out.txt","w",stdout); 91 while(scanf("%d",&n) == 1) 92 { 93 tot = 0; 94 for(int i = 1;i <= n;i++) 95 scanf("%d",&a[i]); 96 T[n+1] = build(1,n); 97 map<int,int>mp; 98 for(int i = n;i>= 1;i--) 99 { 100 if(mp.find(a[i]) == mp.end()) 101 { 102 T[i] = update(T[i+1],i,1); 103 } 104 else 105 { 106 int tmp = update(T[i+1],mp[a[i]],-1); 107 T[i] = update(tmp,i,1); 108 } 109 mp[a[i]] = i; 110 } 111 scanf("%d",&q); 112 while(q--) 113 { 114 int l,r; 115 scanf("%d%d",&l,&r); 116 printf("%d\n",query(T[l],r)); 117 } 118 } 119 return 0; 120 }
人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想