zoukankan      html  css  js  c++  java
  • Codeforces 1490G

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


    题意

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

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

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

    若不存在,输出(-1)


    限制

    (1le Tle 10^4)

    (1le n,mle 2cdot 10^5)

    (-10^9le a_ile 10^9)

    (1le x_ile 10^9)

    (sum nle 2cdot 10^5, sum mle 2cdot 10^5)




    思路

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


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

    根据({M})的定义

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

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

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

    • 如果(S_nle 0),又因为此时(M_nlt x),所以不存在任何一种状态满足(S_ige x),故输出(-1)
    • 如果(S_ngt 0)

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

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

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

    据上述,得到(M_n+lceilfrac d {S_n} ceil*S_nge x)

    (M_nge x-lceilfrac d {S_n} ceil*S_n)

    故让(x)减去(lceilfrac d {S_n} ceil*S_n)后,便能通过二分查找来直接找到最小下标,最后将下标加上(lceilfrac d {S_n} ceil*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<<'
    ';
    }
    
    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

  • 相关阅读:
    cin 与 getline
    ubuntu换源
    unbuntu 安装 bochs
    np.random.randint()的返回值
    vs2019 写入访问权限冲突
    44.Android之Shape设置虚线、圆角和渐变学习
    43.Android之ListView中BaseAdapter学习
    42.Android之ListView中ArrayAdapter简单学习
    Java编程思想学习(十六) 并发编程
    Java编程思想学习(十五) 注解
  • 原文地址:https://www.cnblogs.com/stelayuri/p/14408083.html
Copyright © 2011-2022 走看看