Codeforces 1490G - Old Floppy Drive (二分、数学)

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


题意

给定一个包含\(n\)个整数的数组\(\{a\}\),可以循环延申至无穷个元素(定义编号\(n\)的后一个元素为编号\(1\)

再给定\(m\)个询问\(x\),对于每个\(x\)

问无穷数组\(\{a\}\)前缀和数组\(\{S\}\)中,第一次出现\(S_i\ge x\)的下标\(i\)是多少(输出时下标要\(-1\)

若不存在,输出\(-1\)


限制

\(1\le T\le 10^4\)

\(1\le n,m\le 2\cdot 10^5\)

\(-10^9\le a_i\le 10^9\)

\(1\le x_i\le 10^9\)

\(\sum n\le 2\cdot 10^5,\ \sum m\le 2\cdot 10^5\)




思路

注意求的是第一次出现\(a_i\ge x\)的下标\(i\),不是\(a_i=x\)(读错题了,可惜)


\(S_k=\sum_{i=1}^k a_i,\ M_k=\max_{i=1}^k S_i\)

根据\(\{M\}\)的定义

如果\(M_n\ge x\),说明答案存在于\(1\)\(n\)之间

又因为\(\{M\}\)是非递减数组,所以可以通过二分查找来直接找到最小下标

否则,对\(S_n\)的正负性质进行讨论

  • 如果\(S_n\le 0\),又因为此时\(M_n\lt x\),所以不存在任何一种状态满足\(S_i\ge x\),故输出\(-1\)
  • 如果\(S_n\gt 0\)

根据题意,\(S_{i+n}=S_i+S_n\)

定义\(d=x-M_n\),表示询问的值与\(1\)\(n\)中所能得到最大的值的差值

于是发现,要想得到大于等于\(x\)的数,\(1\)\(n\)中的最大值\(M_n\)还需要加上\(\lceil\frac d {S_n}\rceil\)\(S_n\)才行

据上述,得到\(M_n+\lceil\frac d {S_n}\rceil*S_n\ge x\)

\(M_n\ge x-\lceil\frac d {S_n}\rceil*S_n\)

故让\(x\)减去\(\lceil\frac d {S_n}\rceil*S_n\)后,便能通过二分查找来直接找到最小下标,最后将下标加上\(\lceil\frac d {S_n}\rceil*n\)即为答案




代码

(202ms/2000ms)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll mx[200050];

void solve()
{
    int n,m;
    cin>>n>>m;
    
    ll s=0;
    for(int i=1;i<=n;i++)
    {
        ll d;
        cin>>d;
        s+=d;
        mx[i]=max(mx[i-1],s);
    }
    
    while(m--)
    {
        ll q;
        cin>>q;
        if(mx[n]>=q)
            cout<<(lower_bound(mx+1,mx+1+n,q)-mx)-1<<' ';
        else
        {
            if(s<=0)
                cout<<"-1 ";
            else
            {
                ll d=q-mx[n];
                ll tim=(d+s-1)/s;
                q-=tim*s;
                cout<<(lower_bound(mx+1,mx+1+n,q)-mx+tim*n)-1<<' ';
            }
        }
    }
    cout<<'\n';
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;cin>>T;while(T--)
        solve();
    return 0;
}

https://blog.csdn.net/qq_36394234/article/details/113830619

posted @ 2021-02-17 01:44  StelaYuri  阅读(90)  评论(0编辑  收藏  举报