poj2104 主席树模板题

题意

给出n个数字组成的数字序列,有m组询问。每次询问包含三个数字l,r,k。对于每个询问输出序列区间[l,r]中第k大的数字。

分析

这是主席树的模板题,套板子就可以

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 using namespace std;
 6 const int maxn=100000+10;
 7 struct Value{
 8     int x;
 9     int id;
10     bool operator <(const Value &rhs)const{
11         return x<rhs.x;
12     }
13 }value[maxn];
14 int n,m,num,cnt;
15 int lc[20*maxn],rc[20*maxn],sumv[20*maxn];
16 int a[maxn],root[maxn],Rank[maxn];
17 void update(int num,int old,int &o,int L,int R){
18     o=++cnt;
19     lc[o]=lc[old],rc[o]=rc[old],sumv[o]=sumv[old];
20     sumv[o]++;
21     if(L==R)return ;
22     int M=L+(R-L)/2;
23     if(num<=M)update(num,lc[o],lc[o],L,M);
24     if(num>M)update(num,rc[o],rc[o],M+1,R);
25 }
26 int query(int i,int j,int k,int L,int R){
27     int lsum=sumv[lc[j]]-sumv[lc[i]];
28     if(L==R)return L;
29     int M=L+(R-L)/2;
30     if(lsum>=k)return query(lc[i],lc[j],k,L,M);
31     else return query(rc[i],rc[j],k-lsum,M+1,R);
32 }
33 int main(){
34     scanf("%d%d",&n,&m);
35     for(int i=1;i<=n;i++){
36             scanf("%d",&a[i]);
37             value[i].x=a[i];
38             value[i].id=i;
39     }
40     sort(value+1,value+1+n);
41     for(int i=1;i<=n;i++){
42         Rank[value[i].id]=i;
43     }
44     num=1,cnt=0;
45     for(int i=1;i<=n;i++){
46             update(Rank[i],root[i-1],root[i],1,n);
47     }
48     int l,r,k;
49     for(int i=1;i<=m;i++){
50         scanf("%d%d%d",&l,&r,&k);
51         printf("%d\n",value[query(root[l-1],root[r],k,1,n)].x);
52     }
53 return 0;
54 }
View Code

 

posted @ 2018-04-13 23:52  蒟蒻LQL  阅读(232)  评论(0编辑  收藏  举报