主席树 找区间内不同的数

越来越觉得主席树这个东西需要意会了……太TM深奥了TAT (๑•̀ㅂ•́)و✧

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #define REP(i, s, n) for(int i = s; i <= n; i ++)
 7 #define RAP(i, n, s) for(int i = n; i >= s; i --)
 8 using namespace std;
 9 const int maxn = 100000 + 10;
10 const int maxnode = 20 * maxn;
11 int ls[maxnode], rs[maxnode], root[maxn], s[maxnode];
12 int A[maxn], num[maxn], last[maxn], from[maxn], n, Q, ms;
13 int find(int v){
14     int L = 1, R = n, M;
15     while(L <= R){
16         M = L + R >> 1;
17         if(num[M] < v) L = M + 1;
18         else R = M - 1;
19     }
20     return L;
21 }
22 void build(int x, int& y, int L, int R, int v){
23     s[y = ++ ms] = s[x] + 1;
24     if(L == R) return ;
25     rs[y] = rs[x]; ls[y] = ls[x];
26     int M = L + R >> 1;
27     if(v <= M) build(ls[x], ls[y], L, M, v);
28     else build(rs[x], rs[y], M + 1, R, v);
29     return ;
30 }
31 int query(int x, int& y, int L, int R, int v){
32     if(L == R) return s[y] - s[x]; //把数量扔回来Σ( ° △ °|||) ︴Σ( ° △ °|||) ︴Σ( ° △ °|||)︴ 
33     int M = L + R >> 1;
34     if(v <= M) return query(ls[x], ls[y], L, M, v);
35     else return (s[ls[y]] - s[ls[x]]) + query(rs[x], rs[y], M + 1, R, v); //左边的别忘加了,注意是孩子的o(* ̄3 ̄)o 
36 }
37 void read(int &x){
38     x = 0; int sig = 1; char ch = getchar();
39     while(!isdigit(ch)) { if(ch == '-') sig = -1; ch = getchar(); }
40     while(isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
41     x *= sig; return ;
42 }
43 void init(){
44     read(n); read(Q);
45     REP(i, 1, n) read(A[i]), num[i] = A[i];
46     sort(num + 1, num + 1 + n);
47     REP(i, 1, n){
48         build(root[i - 1], root[i], 0, n, last[from[i] = find(A[i])]);//每次更新一下头,去建“尾”的主席树 
49         last[from[i]] = i;//别忘了更新现在到哪里了
50     }
51     return ;
52 }
53 void work(){
54     int L, R;
55     while(Q --){
56         read(L); read(R);
57         printf("%d\n", query(root[L - 1], root[R], 0, n, L - 1)); //你想想啊我们要找在这个范围内最后出现在L-1里东西的数量吧? 
58     }
59     return ;
60 }
61 void print(){
62 
63     return ;
64 }
65 int main(){
66     init();
67     work();
68     print();
69     return 0;
70 }

 

你可能感兴趣的:(树)