A - 低阶入门膜法 - K-th Number (主席树查询区间第k小)

题目链接:https://cn.vjudge.net/contest/284294#problem/A

题目大意:主席树查询区间第k小。

具体思路:主席树入门。

AC代码:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<vector>
 5 using namespace std;
 6 # define ll long long
 7 const int maxn = 1e5+10;
 8 struct node
 9 {
10     int sum;
11     int l,r;
12 } tree[maxn*80];
13 int sto[maxn],root[maxn];
14 vector<int>q;
15 int tot;
16 void init()
17 {
18     tot=0;
19     root[0]=0;
20 }
21 int get_id(int t)
22 {
23     return lower_bound(q.begin(),q.end(),t)-q.begin()+1;
24 }
25 int add(int pre)
26 {
27     int t=++tot;
28     tree[t].sum=tree[pre].sum+1;
29     tree[t].l=tree[pre].l;
30     tree[t].r=tree[pre].r;
31     return t;
32 }
33 void update(int &o,int pre,int l,int r,int pos)
34 {
35     o=add(pre);
36     if(l==r)return ;
37     int m=(l+r)>>1;
38     if(pos<=m)update(tree[o].l,tree[o].l,l,m,pos);
39     else update(tree[o].r,tree[o].r,m+1,r,pos);
40 }
41 int query(int st,int ed,int l,int r,int k){
42 if(l==r)return r;
43 int sum=tree[tree[ed].l].sum-tree[tree[st].l].sum;
44 int m=(l+r)>>1;
45 if(k<=sum)return query(tree[st].l,tree[ed].l,l,m,k);
46 else return query(tree[st].r,tree[ed].r,m+1,r,k-sum);
47 }
48 int main()
49 {
50     int n,m;
51     while(~scanf("%d %d",&n,&m))
52     {
53         init();
54         for(int i=1; i<=n; i++)
55         {
56             scanf("%d",&sto[i]);
57             q.push_back(sto[i]);
58         }
59         sort(q.begin(),q.end());
60         q.erase(unique(q.begin(),q.end()),q.end());
61         int num=q.size();
62         for(int i=1; i<=n; i++)
63         {
64             update(root[i],root[i-1],1,num,get_id(sto[i]));
65         }
66         int t1,t2,k;
67         while(m--){
68         scanf("%d %d %d",&t1,&t2,&k);
69         printf("%d\n",q[query(root[t1-1],root[t2],1,num,k)-1]);
70         }
71     }
72     return 0;
73 }

 

posted @ 2019-02-20 11:30  Let_Life_Stop  阅读(289)  评论(0编辑  收藏  举报