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 }
View Code

 

比较习惯的递归版:

 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 }

 

posted @ 2016-09-27 23:13  Naturain  阅读(261)  评论(0编辑  收藏  举报