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

質問の意味
n個の数字がリングを形成するために与えられます。最初の数字の位置の始めで、各動きは1つの正方形を下に移動することです。
mクエリ、各クエリはx、少なくとも何回移動する必要があるか、および渡された値の合計≥xを与えますか?

アイデア
クエリ数。明らかに、各クエリにはログが必要です。
接頭辞と合計を維持し、接頭辞の合計maの最大値を維持します
。xの場合、ma [n]以下の場合、つまり、完全に移動しなくても答えを見つけることができます。簡単です。 maが単調であり、2つに分割できることを知るために。すぐに見つけてください。
残りの部分については、ma [n] <xを意味します。次に、xが正であるため、各ラウンド後にサイズが増加するかどうかを確認する必要があります。
sum [n] <= 0の場合、1ラウンド後に増加せず、到達しないことを示し、-1を出力します。
それ以外の場合は、k * sum [n] + sum [o]> = xとなるような最小のkが必要です。その場合、
答えはk * n + oになります。
答えをできるだけ小さくしたいので、kを最小化する必要があります。したがって、ここに合計[o]が最大になり、実際にはma [n]になります。
その場合、完了する実行の数は(x-ma [n])/ sum [n]です。これは切り上げられるため、
(x-ma [n] -1)/ sum [n] +1の
場合oの位置最初の位置は2点で見つけることができます。


#include<bits/stdc++.h>
using namespace std;
const int N=3e5;
typedef long long ll;
ll sum[N],ma[N];
int main(){
    
    
    ma[0]=-2e9;
    int T;cin>>T;
    while(T--){
    
    
        int n,m;cin>>n>>m;
        for(int i=1;i<=n;i++){
    
    
            int x;cin>>x;
            sum[i]=sum[i-1]+x;
            ma[i]=max(ma[i-1],sum[i]);
        }
        while(m--){
    
    
            int x;cin>>x;
            if(ma[n]>=x){
    
    
                int ans=lower_bound(ma+1,ma+n+1,x)-ma;
                cout<<ans-1<<" ";
            }
            else{
    
    
                if(sum[n]<=0) cout<<-1<<" ";
                else{
    
    
                    ll cnt=(x-ma[n]-1)/sum[n]+1;
                    x-=cnt*sum[n];
                    int pos=lower_bound(ma+1,ma+n+1,x)-ma;
                    cout<<cnt*n+pos-1<<" ";

                }
            }
        }
        cout<<endl;
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/qq_43563669/article/details/113851969