19暑假主席树C

本文详细解析了C-Justhhh-index算法,这是一种用于计算作者h指数的高效算法。通过给定数组,算法能够快速求解子数组中h值,适用于大量数据查询场景。文章提供了完整的代码实现,包括预处理、二分查找和第k大元素的求解方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C - Just hhh-index
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

  • 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
    h为一个数组中最大的h使数组中大于等于h的数字个数大于等于h
    给一个数组,每次询问子数组中h值
    设数组长度为len,即数组中第h大的数字大于等于h
    h范围在1到len之间,二分加第k大即可求出答案

    #include<stdio.h>
    #include
    #include
    #define maxl 100005
    using namespace std;
    int n,q;
    int nn,tot;
    int rt[maxl],a[maxl],b[maxl];
    struct node
    {
    int ls,rs,sum;
    }tree[maxl*20];
    void insert(int num,int &x,int l,int r)
    {
    tree[++tot]=tree[x];
    x=tot;
    ++tree[x].sum;
    if(l==r) return;
    int mid=(l+r)>>1;
    if(num<=mid)
    insert(num,tree[x].ls,l,mid);
    else
    insert(num,tree[x].rs,mid+1,r);
    }

    void prework()
    {
    tree[0].ls=tree[0].rs=tree[0].sum=0;
    rt[0]=0;
    for(int i=1;i<=n;i++)
    {
    scanf("%d",&a[i]);
    b[i]=a[i];
    }
    sort(b+1,b+1+n);
    nn=unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=n;i++)
    a[i]=lower_bound(b+1,b+nn+1,a[i])-b;
    tot=0;
    for(int i=1;i<=n;i++)
    {
    rt[i]=rt[i-1];
    insert(a[i],rt[i],1,nn);
    }
    }

    int query(int i,int j,int k,int l,int r)
    {
    if(l==r)
    return l;
    int tp=tree[tree[j].ls].sum-tree[tree[i].ls].sum;
    int mid=(l+r)>>1;
    if(k<=tp)
    return query(tree[i].ls,tree[j].ls,k,l,mid);
    else
    return query(tree[i].rs,tree[j].rs,k-tp,mid+1,r);
    }
    int main()
    {
    while(~scanf("%d%d",&n,&q))
    {
    tot=0;
    prework();
    while(q–)
    {
    int L,R;
    scanf("%d%d",&L,&R);
    int l=1,r=R-L+1;
    while(r>l+1)
    {
    int mid=(l+r)/2;
    if(b[query(rt[L-1],rt[R],R-L-mid+2,1,nn)]>=mid)
    l=mid;
    else
    r=mid;
    }
    if(b[query(rt[L-1],rt[R],R-L-r+2,1,nn)]>=r)
    printf("%d\n",r);
    else
    printf("%d\n",l);
    }
    }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值