HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6278

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)

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.
 
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.
 
Output
For each question, print an integer which denotes the answer.

## Constraint
1n,q105
1ain
1lirin
* 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

 

题意:

一个作者它的“h-index”指的是:有一个最大的正整数h,且满足他有至少h篇论文的引用量不低于h。

现在给出n篇论文的引用量,m个区间[L,R]的查询,询问假设他只发了[L,R]这个区间内的这些论文,则他的h-index为多少。

 

题解:

当初比赛的时候不会主席树,也不会莫队,只能拿着普通的线段树在那里硬刚,结果十分凄惨。

现在会了分块版的莫队算法,回来补题了。

考虑num[c]表示引用量为c的文章数,那么用树状数组维护就可以 $Oleft( {log _2 N} ight)$ 的进行单点修改、区间查询,正好符合题目要求;

所以我们每次区间转移进行 $Oleft( {log _2 N} ight)$ 的进行单点修改,

然后转移结束之后,当前区间的答案(h_index)就可以通过 二分查找 + $Oleft( {log _2 N} ight)$ 的区间查询 得到。

时间复杂度大概在 $Oleft( {N cdot sqrt N cdot left( {log _2 N} ight)^2 } ight)$,从理论上讲应该可以过。

 

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
const int MAXM=1e5+10;

int n,m;
int citation[MAXN];
int h_idx[MAXM];
struct Query
{
    int block;
    int id;
    int l,r;
    bool operator <(const Query &oth) const
    {
        if(block==oth.block) return r<oth.r;
        return block<oth.block;
    }
}query[MAXM];

struct _BIT{
    int N,C[MAXN];
    int lowbit(int x){return x&(-x);}
    void init(int n)//初始化共有n个点
    {
        N=n;
        for(int i=1;i<=N;i++) C[i]=0;
    }
    void add(int pos,int val)//在pos点加上val
    {
        while(pos<=N)
        {
            C[pos]+=val;
            pos+=lowbit(pos);
        }
    }
    int sum(int pos)//查询1~pos点的和
    {
        int ret=0;
        while(pos>0)
        {
            ret+=C[pos];
            pos-=lowbit(pos);
        }
        return ret;
    }
}BIT;

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int len=sqrt(n);
        for(int i=1;i<=n;i++) scanf("%d",&citation[i]);

        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&query[i].l,&query[i].r);
            query[i].block=query[i].l/len;
            query[i].id=i;
        }
        sort(query+1,query+m+1);

        BIT.init(n);
        int pl=1;
        int pr=0;
        int cnt=0;
        for(int i=1;i<=m;i++)
        {
            if(pr<query[i].r)
            {
                for(int j=pr+1;j<=query[i].r;j++)
                {
                    BIT.add(citation[j],1);
                    cnt++;
                }
            }
            if(pr>query[i].r)
            {
                for(int j=pr;j>query[i].r;j--)
                {
                    BIT.add(citation[j],-1);
                    cnt--;
                }
            }
            if(pl<query[i].l)
            {
                for(int j=pl;j<query[i].l;j++)
                {
                    BIT.add(citation[j],-1);
                    cnt--;
                }
            }
            if(pl>query[i].l)
            {
                for(int j=pl-1;j>=query[i].l;j--)
                {
                    BIT.add(citation[j],1);
                    cnt++;
                }
            }
            pl=query[i].l;
            pr=query[i].r;

            int l=1,r=n,mid;
            while(l<r)
            {
                mid=(l+r+1)/2;
                if(cnt-BIT.sum(mid-1)<mid) r=mid-1;
                else l=mid;
            }

            h_idx[query[i].id]=r;
        }

        for(int i=1;i<=m;i++) printf("%d
",h_idx[i]);
    }
}

 
















以上是关于HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]的主要内容,如果未能解决你的问题,请参考以下文章

HDU 6278 主席树(区间第k大)+二分

Just h-index

主席树的妙用——Just h-index

2019牛客国庆集训派对day2 C.Just h-index(主席树)

2019牛客国庆集训派对day2 C Just h-index 二分答案+主席树

HDU 6276 Easy h-index(思维+二分/前缀和)