Just h-index
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
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
解题思路:读懂题意之后,直接上莫队。用树状数组维护后缀和(总-前缀和),然后二分答案即可。
当然对于求后缀和部分,可以直接用主席树求,速度更快这样就不用莫队了。
莫队+二分+树状数组
#include <iostream> #include <algorithm> #include <cstdio> #include <string.h> using namespace std; typedef long long int ll; const int MAXN=100015; int N,Q; int a[MAXN]; struct query{ int l; int r; int id; }q[MAXN]; int block[MAXN]; int blocksize; bool cmp(query a,query b){ if(block[a.l]==block[b.l]) return a.r<b.r; return block[a.l]<block[b.l]; } int ans[MAXN]; int tree[MAXN]; int tot=0; int lowbit(int x){ return x&-x; } void add(int x,int C){ for(int i=x;i<=MAXN;i+=lowbit(i)){ tree[i]+=C; } } int sum(int x){ int ans=0; for(int i=x;i;i-=lowbit(i)) ans+=tree[i]; return ans; } bool judge(int x){ // cout<<x<<" "<<tot<<" "<<sum(x-1)<<endl; if(tot-sum(x-1)-x>=0) return true; return false; } void solve(){ int l=1; int r=1; tot++; add(a[1],1); for(int i=0;i<Q;i++){ // cout<<q[i].r<<q[i].r<<endl; while (q[i].r > r) { r++; add(a[r],1); tot++; } while (q[i].r < r){ add(a[r],-1); r--; tot--; } while (q[i].l > l) { add(a[l],-1); l++; tot--; } while (q[i].l < l) { l--; add(a[l],1); tot++; } int ll=1,rr=N; int m; while(ll<=rr){ m=(ll+rr)/2; if(judge(m)){ ll=m+1; } else rr=m-1; } ans[q[i].id]=rr; } } int main() { while(~scanf("%d%d",&N,&Q)){ tot=0; memset(tree,0,sizeof(tree)); blocksize=sqrt(N); for(int i=1;i<=N;i++){ scanf("%d",&a[i]); block[i]=(i-1)/blocksize+1; } for(int i=0;i<Q;i++){ scanf("%d%d",&q[i].l,&q[i].r); q[i].id=i; } sort(q,q+Q,cmp); solve(); for(int i=0;i<Q;i++) { printf("%d\n",ans[i]); } } return 0; }
主席树+二分
#include <iostream> #include <algorithm> #include <cstdio> #include <string.h> using namespace std; typedef long long int ll; const int MAXN=100015; int N,Q; int sum[MAXN*20]; int ls[MAXN*20]; int rs[MAXN*20]; int T[MAXN]; int tot=0; void update(int P,int C,int l,int r,int &rt,int lrt){ rt=++tot; ls[rt]=ls[lrt]; rs[rt]=rs[lrt]; sum[rt]=sum[lrt]; if(l==r){ sum[rt]+=C; return; } int m=(l+r)/2; if(P<=m) update(P,C,l,m,ls[rt],ls[lrt]); else update(P,C,m+1,r,rs[rt],rs[lrt]); sum[rt]=sum[ls[rt]]+sum[rs[rt]]; } int query(int L,int R,int l,int r,int rt,int lrt){ if(L<=l&&r<=R){ return sum[lrt]-sum[rt]; } int m=(l+r)/2; int ans=0; if(L<=m) ans+=query(L,R,l,m,ls[rt],ls[lrt]); if(R>m) ans+=query(L,R,m+1,r,rs[rt],rs[lrt]); return ans; } bool judge(int x,int l,int r){ if(query(x,N,1,N,T[l-1],T[r])-x>=0) return true; return false; } int main() { while(~scanf("%d%d",&N,&Q)){ tot=0; memset(sum,0,sizeof(sum)); memset(ls,0,sizeof(ls)); memset(rs,0,sizeof(rs)); int a; for(int i=1;i<=N;i++){ scanf("%d",&a); update(a,1,1,N,T[i],T[i-1]); } int l,r; for(int i=0;i<Q;i++){ scanf("%d%d",&l,&r); int ll=1,rr=N; int m; while(ll<=rr){ m=(ll+rr)/2; if(judge(m,l,r)){ ll=m+1; } else rr=m-1; } printf("%d\n",rr); } } return 0; }