Codeforces Round #702 (Div. 3) G. Old Floppy Drive

结构体lower_bound

思路很简单,之前在牛客写过一道类似的题目,那道题的题面是勇者屠恶龙打BOSS,可以除一下然后直接暴力,这道不行,要用二分查找,1900标高了。

记录一下a数组总和sum和最大值Max,可以算出答案所在轮次,然后再二分查找具体的下标,有一个细节就是可以在记录Max的时候把每次更新Max的值用结构体存起来,因为如果后面的值比当前更新的值小的话那就没有意义,后面直接二分这个结构体数组就可以。

#include<bits/stdc++.h>
#define LL long long
#define INF INT64_MAX
#define MOD 1000000007
#define stree SegTree[root]
#define lson SegTree[root << 1]
#define rson SegTree[root << 1 | 1]
using namespace std;
const int N = 200005;
LL a[N];
struct node
{
    LL val, pos;
    bool operator < (const node &b) const
    {
        if(val!=b.val) return val<b.val;
        else return pos>b.pos;
    }
}b[N], tem;
int main()
{
    int t, n, m, x;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        LL sum = 0, Max = -INF, cnt = 0;
        for(int i = 1;i <= n;i++)
        {
            cin>>a[i];
            sum += a[i];
            if(sum>Max)
            {
                b[cnt].val = sum;
                b[cnt++].pos = i;
            }
            Max = max(Max, sum);
        }
        while(m--)
        {
            cin>>x;
            tem.pos = INF;
            if(Max<x && sum<=0) printf("-1 ");
            else
            {
                LL ans = 0;
                tem.val = x;
                if(x>Max)
                {
                     ans = ((x-Max+sum-1)/sum)*n;
                     tem.val = x-((x-Max+sum-1)/sum)*sum;
                }
                int it = lower_bound(b, b+cnt, tem)-b;
                printf("%lld ", ans-1+b[it].pos);
            }
        }
        printf("\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值