Just h-index(主席树裸题)

Just h-index

题意:输入第一行给了\(n\),\(q\),代表有\(n\)个数\(q\)次询问,第二行给出这\(n\)个数,每次询问一个区间,答出一个最大的数\(h\)使得这个区间里大于等于\(h\)的数的个数大于等\(h\)。

题解:见代码吧,比较好理解的,主席树

AC_Code:

 1 //主席树是多个权值线段树
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 using namespace std;
 8 typedef long long ll;
 9 typedef long double ld;
10 #define endl '\n'
11 const int inf=0x3f3f3f3f;
12 const int maxn=1e5+10;
13 const int maxm=5e5+10;
14 
15 struct node{
16     int l,r,sum;
17 }T[maxn*50];
18 int root[maxn],cnt;
19 int n,q,a[maxn],maxx;
20 
21 void update(int l,int r,int &x,int y,int pos){
22     T[++cnt]=T[y], T[cnt].sum++, x=cnt;
23     if( l==r ) return ;
24     int mid=(l+r)>>1;
25     if( pos>mid ) update(mid+1,r,T[x].r,T[y].r,pos);
26     else update(l,mid,T[x].l,T[y].l,pos);
27 }
28 
29 int query(int l,int r,int x,int y,int sum){
30     if( l==r ) return l;    //返回的就是所需的编号
31     int mid=(l+r)>>1;
32     int Rsum=T[T[y].r].sum - T[T[x].r].sum;
33     if( Rsum+sum>mid ) return query(mid+1,r,T[x].r,T[y].r,sum);  //有一种前缀后缀和的感觉(好好感受一下)
34     else return query(l,mid,T[x].l,T[y].l,Rsum+sum);
35 }
36 
37 int main()
38 {
39     while( ~ scanf("%d%d",&n,&q)){
40         cnt=0;
41         memset(T,0,sizeof(T));
42         maxx=0;
43 
44         for(int i=1;i<=n;i++){
45             scanf("%d",&a[i]);
46             maxx=max(maxx,a[i]);
47         }
48         for(int i=1;i<=n;i++){
49             update(1,maxx,root[i],root[i-1],a[i]);
50         }
51         while( q-- ){
52             int l,r; scanf("%d%d",&l,&r);
53             printf("%d\n",query(1,maxx,root[l-1],root[r],0));
54         }
55     }
56     return 0;
57 }

 

posted @ 2020-08-16 18:27  swsyya  阅读(202)  评论(0编辑  收藏  举报

回到顶部