标签:
主席树真是神奇的物种!
题意:给n、m
下面有n个数 (编号1到n)
有m个询问,询问的是上面的数的编号在[l,r]之间第k小的数
n、m的范围都是1e5
是主席树的入门题
借此来学习一下主席树
1 const int N=1e5+5; 2 int L[N<<5], R[N<<5], sum[N<<5]; 3 int tot; 4 int a[N], T[N], Hash[N]; 5 int build(int l, int r) 6 { 7 int rt=(++tot); 8 sum[rt]=0; 9 if(l<r) 10 { 11 int m=(l+r)>>1; 12 L[rt]=build(lson); 13 R[rt]=build(rson); 14 } 15 return rt; 16 } 17 18 int update(int pre, int l, int r, int x) 19 { 20 int rt=(++tot); 21 L[rt]=L[pre], R[rt]=R[pre], sum[rt]=sum[pre]+1; 22 if(l<r) 23 { 24 int m=(l+r)>>1; 25 if(x<=m) 26 L[rt]=update(L[pre], lson, x); 27 else 28 R[rt]=update(R[pre], rson, x); 29 } 30 return rt; 31 } 32 33 int query(int u, int v, int l, int r, int k) 34 { 35 if(l>=r) 36 return l; 37 int m=(l+r)>>1; 38 int num=sum[L[v]]-sum[L[u]]; 39 if(num>=k) 40 return query(L[u], L[v], lson, k); 41 else 42 return query(R[u], R[v], rson, k-num); 43 } 44 45 int main() 46 { 47 // int t; 48 // scanf("%d", &t); 49 // while(t--) 50 // { 51 tot=0; 52 int n, m; 53 scanf("%d%d", &n, &m); 54 for(int i=1; i<=n; i++) 55 { 56 scanf("%d", &a[i]); 57 Hash[i]=a[i]; 58 } 59 sort(Hash+1, Hash+n+1); 60 int d=unique(Hash+1, Hash+n+1)-Hash-1; 61 T[0]=build(1, d); 62 for(int i=1; i<=n; i++) 63 { 64 int x=lower_bound(Hash+1, Hash+d+1, a[i])-Hash; 65 T[i]=update(T[i-1], 1, d, x); 66 } 67 while(m--) 68 { 69 int l, r, k; 70 scanf("%d%d%d", &l, &r, &k); 71 int x=query(T[l-1], T[r], 1, d, k); 72 printf("%d\n", Hash[x]); 73 } 74 // } 75 }
[主席树]HDOJ2665 && POJ2104 && POJ2761
标签:
原文地址:http://www.cnblogs.com/Empress/p/4652449.html