首页 > 其他 > 详细

2019 徐州icpc网络赛 E. XKC's basketball team

时间:2019-09-08 00:50:45      阅读:234      评论:0      收藏:0      [点我收藏+]

题库链接:

https://nanti.jisuanke.com/t/41387

题目大意

给定n个数,与一个数m,求ai右边最后一个至少比ai大m的数与这个数之间有多少个数

思路

对于每一个数,利用二分的方法求他右边大于等于ai+m的数的最后一个值。

关键在于怎么二分呢?

利用线段树存储区间最大值,看这个区间的最大值是不是比ai+m大

代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
#define mod 1000000007
int a[maxn];
struct node
{
    int l,r,ma;
}tree[maxn*4];
void build(int l,int r,int p)
{
    tree[p].l = l;
    tree[p].r = r;
    tree[p].ma = -1;
    if(l == r)
    {
        tree[p].ma = a[l];
        return;
    }
    int mid = (l+r)/2;
    build(l,mid,p*2);
    build(mid+1,r,p*2+1);
    tree[p].ma = max(tree[p*2].ma,tree[p*2+1].ma);
}
int query(int x,int y,int p)
{
    if(x == tree[p].l && y == tree[p].r)
        return tree[p].ma;
    int mid = (tree[p].l + tree[p].r)/2;
    if(x > mid)
        return query(x,y,p*2+1);
    else if(y <= mid)
        return query(x,y,p*2);
    else
        return max(query(x,mid,p*2),query(mid+1,y,p*2+1));
 
}
int main()
{
    int T,i,j,k,n,q,x,y,m,s,l,r,mid;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;++i)
        scanf("%d",&a[i]);
    build(1,n,1);
    for(i=1;i<n;i++)
    {
        s=m+a[i];
        l=i+1;
        r=n;
        while(l<r)
        {
              mid=(l+r+1)/2;
             if(query(mid,r,1)>=s)
            {
                l=mid;
             }
             else if(query(l,mid,1)>=s)
             {
                 r=mid-1;
             }
             else 
             {
                  break;
             }
        }
        if(a[l]>=s)
        cout<<l-i-1<< ;
        else
        cout<<"-1"<< ;
    }
    cout<<"-1"<<endl;
    return 0;
}

 

2019 徐州icpc网络赛 E. XKC's basketball team

原文:https://www.cnblogs.com/dyhaohaoxuexi/p/11484004.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!