SPOJ - 3267. D-query 主席树求区间个数

SPOJ - 3267

主席树的又一种写法。 从后端点开始添加主席树, 然后如果遇到出现过的元素先把那个点删除, 再更新树, 最后查询区间就好了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 //#define lson l,m,rt<<1
10 //#define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod =  (int)1e9+7;
16 const int N = 3e4 + 100;
17 const int M = 1e6 + 100;
18 int root[N], lson[M], rson[M], cnt[M];
19 int a[N];
20 map<int,int> mp;
21 int tot;
22 int Build(int l, int r){
23     int now = ++tot;
24     cnt[now] = 0;
25     if(l < r){
26         int m = l+r >> 1;
27         lson[now] = Build(l, m);
28         rson[now] = Build(m+1, r);
29     }
30     return now;
31 }
32 int Update(int l, int r, int pre, int c, int v){
33     int now = ++tot;
34     cnt[now] = cnt[pre] + v;
35     if(l < r){
36         int m = l+r >> 1;
37         if(c <= m){
38             rson[now] = rson[pre];
39             lson[now] = Update(l, m, lson[pre], c, v);
40         }
41         else {
42             lson[now] = lson[pre];
43             rson[now] = Update(m+1, r, rson[pre], c, v);
44         }
45     }
46     return now;
47 }
48 int Query(int l, int r, int p, int R){
49     if(l == r) return cnt[p];
50     int m = l+r >> 1;
51     if(R <= m){
52         return Query(l, m, lson[p], R);
53     }
54     else {
55         return Query(m+1,r,rson[p],R) + cnt[lson[p]];
56     }
57 }
58 int main(){
59     int n;
60     scanf("%d", &n);
61     for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
62     root[n+1] = Build(1, n);
63     for(int i = n; i >= 1; i--){
64         if(mp[a[i]] == 0){
65             root[i] = Update(1, n, root[i+1], i, 1);
66         }
67         else {
68             int tmp = Update(1, n, root[i+1], mp[a[i]], -1);
69             root[i] = Update(1, n, tmp, i, 1);
70         }
71         mp[a[i]] = i;
72     }
73     int m, l, r;
74     scanf("%d", &m);
75     for(int i = 1; i <= m; i++){
76         scanf("%d%d", &l, &r);
77         printf("%d\n", Query(1,n,root[l],r));
78     }
79     return 0;
80     
81 }
SPOJ-3267

猜你喜欢

转载自www.cnblogs.com/MingSD/p/9094322.html