HDU 6278 主席树(区间第k大)+二分
Posted stranger-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6278 主席树(区间第k大)+二分相关的知识,希望对你有一定的参考价值。
Just h-index
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 438 Accepted Submission(s): 203
Problem Description
The h-index of an author is the largest h where he has at least h papers with citations not less than h.
Bobo has published n papers with citations a1,a2,…,an respectively.
One day, he raises q questions. The i-th question is described by two integers li and ri, asking the h-index of Bobo if has *only* published papers with citations ali,ali+1,…,ari.
Bobo has published n papers with citations a1,a2,…,an respectively.
One day, he raises q questions. The i-th question is described by two integers li and ri, asking the h-index of Bobo if has *only* published papers with citations ali,ali+1,…,ari.
Input
The input consists of several test cases and is terminated by end-of-file.
The first line of each test case contains two integers n and q.
The second line contains n integers a1,a2,…,an.
The i-th of last q lines contains two integers li and ri.
The first line of each test case contains two integers n and q.
The second line contains n integers a1,a2,…,an.
The i-th of last q lines contains two integers li and ri.
Output
For each question, print an integer which denotes the answer.
## Constraint
* 1≤n,q≤105
* 1≤ai≤n
* 1≤li≤ri≤n
* The sum of n does not exceed 250,000.
* The sum of q does not exceed 250,000.
## Constraint
* 1≤n,q≤105
* 1≤ai≤n
* 1≤li≤ri≤n
* The sum of n does not exceed 250,000.
* The sum of q does not exceed 250,000.
Sample Input
5 3
1 5 3 2 1
1 3
2 4
1 5
5 1
1 2 3 4 5
1 5
Sample Output
2
2
2
3
Source
补:主席树 2018湘潭C http://acm.hdu.edu.cn/showproblem.php?pid=6278
代码
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; const LL INF = 1E9+9; const int maxn = 1000006; const int LOG = 20; struct node { int l,r; int sum; }Node[maxn*LOG]; int root[maxn],node_cnt; int numbers[maxn],num_cnt; int a[maxn]; void build(int l,int r,int &rt) { rt=++node_cnt; Node[rt].l=Node[rt].r=Node[rt].sum=0; if(l==r) return ; int m=(l+r)>>1; build(l,m,Node[rt].l); build(m+1,r,Node[rt].r); } void update(int v,int l,int r,int &rt,int pre) { rt=++node_cnt; Node[rt]=Node[pre]; ++Node[rt].sum; if(l==r) return ; int m=(l+r)>>1; if(v<=m) update(v,l,m,Node[rt].l,Node[pre].l); else update(v,m+1,r,Node[rt].r,Node[pre].r); } int query(int k,int l,int r,int r1,int r2) { if(l==r) return r; int lnum=Node[Node[r2].l].sum-Node[Node[r1].l].sum; int m=(l+r)>>1; if(k<=lnum) return query(k,l,m,Node[r1].l,Node[r2].l); else return query(k-lnum,m+1,r,Node[r1].r,Node[r2].r); } int main() { // ios::sync_with_stdio(false); int n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) { scanf("%d",&a[i]); // cin>>a[i]; numbers[i]=a[i]; } sort(numbers+1,numbers+n+1); num_cnt=unique(numbers+1,numbers+n+1)-numbers-1; node_cnt=0; root[0]=0; build(1,num_cnt,root[0]); for(int i=1;i<=n;i++) { int pos = lower_bound(numbers+1,numbers+num_cnt+1,a[i])-numbers; update(pos,1,num_cnt,root[i],root[i-1]); } while(m--) { int L,R,K; cin>>L>>R; int l=1,r=R-L+1; int ans=1; //int q=query(K,1,num_cnt,root[L-1],root[R]); //cout<<numbers[q]<<endl; while(l<=r) { int mid=(l+r)/2; int q=query(R-L+2-mid,1,num_cnt,root[L-1],root[R]); //cout<<"mid="<<mid<<" val="<<numbers[q]<<endl; if(numbers[q]>=mid) { ans=max(mid,ans); l=mid+1; } else r=mid-1; } printf("%d ",ans); } } return 0; }
以上是关于HDU 6278 主席树(区间第k大)+二分的主要内容,如果未能解决你的问题,请参考以下文章
hdu 5919 主席树(区间不同数的个数 + 区间第k大)
hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)
HDU6621 K-th Closest Distance 第 k 小绝对值(主席树(统计范围的数有多少个)+ 二分 || 权值线段树+二分)