HDU-6278-Jsut$h$-index(主席树)

链接:

https://vjudge.net/problem/HDU-6278

题意:

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.

思路:

主席树模板,记录每个数字出现的次数,如果某个区间内,数字出现的次数大于等于区间左端点,就往右找,
否则吧右边的所有数累加,往左找,因为右边的数大于左边的数,h是单调的

代码:

#include <iostream>
#include <cstdio>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
using namespace std;
typedef long long LL;
const int MAXN = 1e5+10;

struct Segment
{
    int cnt;
    int l, r;
}Seg[MAXN*30];
int Tree_root[MAXN*30];
int a[MAXN];
int n, m;
int tree_cnt;

int Insert(int num, int last, int l, int r)
{
    tree_cnt++;
    int nownode = tree_cnt;
    Seg[tree_cnt].cnt = Seg[last].cnt+1;
    int mid = (l+r)/2;
    if (l == r)
        return nownode;
    else if (num <= mid)
    {
        Seg[nownode].l = Insert(num, Seg[last].l, l, mid);
        Seg[nownode].r = Seg[last].r;
    }
    else
    {
        Seg[nownode].l = Seg[last].l;
        Seg[nownode].r = Insert(num, Seg[last].r, mid+1, r);
    }
    return nownode;
}

int Query(int x, int y, int l, int r, int num)
{
//    cout << l << ' ' << r << endl;
    if (l == r)
        return l;
    int mid = (l+r)/2;
    int sum = Seg[Seg[y].r].cnt-Seg[Seg[x].r].cnt;
//    cout << sum+num << endl;
    if (sum+num <= mid)
    {
        return Query(Seg[x].l, Seg[y].l, l, mid, num+sum);
    }
    else
    {
        return Query(Seg[x].r, Seg[y].r, mid+1, r, num);
    }
}

void Init()
{
    tree_cnt = 0;
    Seg[0].cnt = 0;
    Tree_root[0] = 0;
}

int main()
{
    while (~scanf("%d %d", &n, &m))
    {
        for (int i = 1;i <= n;i++)
            scanf("%d", &a[i]);
        Init();
        for (int i = 1;i <= n;i++)
        {
            int pos = Insert(a[i], Tree_root[i-1], 1, n);
            Tree_root[i] = pos;
        }
        int x, y;
        while (m--)
        {
            scanf("%d %d", &x, &y);
            printf("%d\n", Query(Tree_root[x-1], Tree_root[y], 1, n, 0));
        }
    }

    return 0;
}
/*
5 3
1 5 3 2 1
1 3
2 4
1 5
5 1000
4 4 4 4 5
1 5
*/
posted @ 2019-07-20 11:02  YDDDD  阅读(213)  评论(0编辑  收藏  举报