求区间x,y内的h-index(最大的h有h篇论文引用量不小于h)
解题思路:
在树上x,y区间内二分答案check
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN = 2e5 + 10;
int fst, lst;
int N;
struct node { int lson, rson, num;} T[MAXN * 32];
int root[MAXN], cnt;
void prt() { cnt = 0; fill(root, root + N + 10, 0);}
void update(int l, int r, int &now, int pre, int a)
{
now = ++cnt;
T[now] = T[pre];
T[now].num++;
if(l == r) return ;
int mid = (l + r) >> 1;
if(a <= mid) update(l, mid, T[now].lson, T[pre].lson, a);
else update(mid + 1, r, T[now].rson, T[pre].rson, a);
}
int sum = 0;
bool gao(int l, int r, int now, int pre, int pos)
{
if(l == r)
{
sum += ( T[now].num - T[pre].num );
return sum >= pos;
}
int mid = (l + r) >> 1;
if(pos <= mid)
{
sum += T[T[now].rson].num - T[T[pre].rson].num;
gao(l, mid, T[now].lson, T[pre].lson, pos);
}
else
{
gao(mid + 1, r, T[now].rson, T[pre].rson, pos);
}
}
int a[MAXN] = {0};
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, m;
while( cin >> n >> m )
{
prt();
N = 0;
for(int i = 1; i <= n; i++)
cin >> a[i], N = max(N, a[i] + 10);
for(int i = 1; i <= n; i++)
update(0, N, root[i], root[i - 1], a[i]);
int a, b;
for(int i = 1; i <= m; i++)
{
cin >> a >> b;
fst = 0, lst = N - 1;
int ans = 0, mid;
while(fst <= lst)
{
mid = (fst + lst) / 2;
sum = 0;
if(gao(0, N, root[b], root[a - 1], mid))
ans = mid, fst = mid + 1;
else
lst = mid - 1;
}
cout << ans << '
';
}
}
return 0;
}