SPOJ--DQUERY(主席树)
2016-09-27 23:10:25
人人都会主席树了,咱不会的话是不是有点落伍?2333~
题意:给定N个数,每次询问一个区间内不同数的个数
思路:主席树,倒序建树,OK,核心思路就是这样。
借鉴bin神的循环版主席树:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <time.h> 5 #include <math.h> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <stack> 10 #include <queue> 11 #include <string> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 17 #define MEM(a,b) memset(a,b,sizeof(a)) 18 #define MP(a,b) make_pair(a,b) 19 #define PB push_back 20 21 typedef long long ll; 22 typedef pair<int,int> pii; 23 const double eps = 1e-8; 24 const int INF = (1 << 30) - 1; 25 const int MAXN = 30010; 26 const int MAX_NLOGN = MAXN * 100; 27 28 int N,Q,tot; 29 int A[MAXN]; 30 int PT[MAXN],lson[MAX_NLOGN],rson[MAX_NLOGN],c[MAX_NLOGN]; 31 map<int,int> mp; 32 33 int Build(int l,int r){ 34 int now = ++tot; 35 c[now] = 0; 36 if(l == r) return now; 37 int mid = getmid(l,r); 38 lson[now] = Build(l,mid); 39 rson[now] = Build(mid + 1,r); 40 return now; 41 } 42 43 int Update(int root,int p,int val){ 44 int now = ++tot,tmp = now; 45 c[now] = c[root] + val; 46 int l = 1,r = N; 47 while(l < r){ 48 int mid = getmid(l,r); 49 if(p <= mid){ 50 lson[now] = ++tot; 51 rson[now] = rson[root]; 52 now = lson[now]; 53 root = lson[root]; 54 r = mid; 55 } 56 else{ 57 rson[now] = ++tot; 58 lson[now] = lson[root]; 59 now = rson[now]; 60 root = rson[root]; 61 l = mid + 1; 62 } 63 c[now] = c[root] + val; 64 } 65 return tmp; 66 } 67 68 int Query(int root,int pos){ 69 int res = 0; 70 int l = 1,r = N; 71 while(pos < r){ 72 int mid = getmid(l,r); 73 if(pos <= mid){ 74 root = lson[root]; 75 r = mid; 76 } 77 else{ 78 res += c[lson[root]]; 79 root = rson[root]; 80 l = mid + 1; 81 } 82 } 83 return res + c[root]; 84 } 85 86 int main(){ 87 scanf("%d",&N); 88 for(int i = 1; i <= N; ++i) scanf("%d",&A[i]); 89 PT[N + 1] = Build(1,N); 90 for(int i = N; i >= 1; --i){ 91 if(mp.find(A[i]) == mp.end()){ 92 PT[i] = Update(PT[i + 1],i,1); 93 } 94 else{ 95 int tmp = Update(PT[i + 1],mp[A[i]],-1); 96 PT[i] = Update(tmp,i,1); 97 } 98 mp[A[i]] = i; 99 } 100 scanf("%d",&Q); 101 for(int i = 1; i <= Q; ++i){ 102 int a,b; 103 scanf("%d%d",&a,&b); 104 printf("%d\n",Query(PT[a],b)); 105 } 106 return 0; 107 }
比较习惯的递归版:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <time.h> 5 #include <math.h> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <stack> 10 #include <queue> 11 #include <string> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 17 #define MEM(a,b) memset(a,b,sizeof(a)) 18 #define MP(a,b) make_pair(a,b) 19 #define PB push_back 20 21 typedef long long ll; 22 typedef pair<int,int> pii; 23 const double eps = 1e-8; 24 const int INF = (1 << 30) - 1; 25 const int MAXN = 30010; 26 const int MAX_NLOGN = MAXN * 100; 27 28 int N,Q; 29 int A[MAXN]; 30 int PT[MAXN],lson[MAX_NLOGN],rson[MAX_NLOGN],c[MAX_NLOGN]; 31 int tot; 32 map<int,int> mp; 33 34 int Build(int l,int r){ 35 int now = ++tot; 36 c[now] = 0; 37 if(l == r) return now; 38 int mid = getmid(l,r); 39 lson[now] = Build(l,mid); 40 rson[now] = Build(mid + 1,r); 41 return now; 42 } 43 44 int Update(int root,int p,int val,int l,int r){ 45 int now = ++tot,tmp = now; 46 int mid = getmid(l,r); 47 c[now] = c[root] + val; 48 if(l == r) return tmp; 49 if(p <= mid){ 50 rson[now] = rson[root]; 51 lson[now] = Update(lson[root],p,val,l,mid); 52 } 53 else{ 54 lson[now] = lson[root]; 55 rson[now] = Update(rson[root],p,val,mid + 1,r); 56 } 57 return tmp; 58 } 59 60 int Query(int root,int pos,int l,int r){ 61 int res = 0,mid = getmid(l,r); 62 if(r <= pos) return c[root]; 63 if(pos <= mid) res = Query(lson[root],pos,l,mid); 64 else res = c[lson[root]] + Query(rson[root],pos,mid + 1,r); 65 return res; 66 } 67 68 int main(){ 69 scanf("%d",&N); 70 for(int i = 1; i <= N; ++i) scanf("%d",&A[i]); 71 PT[N + 1] = Build(1,N); 72 for(int i = N; i >= 1; --i){ 73 if(mp.find(A[i]) == mp.end()){ 74 PT[i] = Update(PT[i + 1],i,1,1,N); 75 } 76 else{ 77 int tmp = Update(PT[i + 1],mp[A[i]],-1,1,N); 78 PT[i] = Update(tmp,i,1,1,N); 79 } 80 mp[A[i]] = i; 81 } 82 scanf("%d",&Q); 83 for(int i = 1; i <= Q; ++i){ 84 int a,b; 85 scanf("%d%d",&a,&b); 86 printf("%d\n",Query(PT[a],b,1,N)); 87 } 88 return 0; 89 }