Codeforces Round # 702 (Div. 3) G. Старый дисковод для гибких дисков (二 分)

Заголовок:

Дайте массив aaa , первый указатель указывает на1 a_1а1, Указатель будет перемещаться назад каждую секунду, когда достигнет a_nаNВернусь к 1 a_1а1, После прохождения элемента значение этого элемента будет получено, когда сумма полученных значений ≥ x \ geq xКогда x , он остановится, теперь задайте несколько запросовxi x_iИксЯИ спросил, когда это прекратится.

отвечать:

Сначала я подумал, что он равен x, а потом остановился.После долгих раздумий я пришел к эффекту.

Сначала найдите префикс и sum [i] sum [i] для каждой позицииs u m [ i ] , принимая максимальное значение суммы префикса, то естьdp [i] = max ⁡ j = 1 isum [j] dp [i] = \ max \ limits_ {j = 1} ^ {i } сумма [j]d p [ i ]знак равноj = 1МаксимумЯs u m [ j ]

Если dp [n] ≥ x dp [n] \ geq xd p [ n ]x , то, поскольку монотонность удовлетворена, двоичный поиск в порядке.

В противном случае, если сумма [n] ≤ 0, сумма [n] \ leq 0с у м [ п ]0 , то он не должен достигать x, напрямую выведите -1.

сумма [n]> 0 сумма [n]> 0с у м [ п ]>0时 ,x - dp [n] x-dp [n]Икс-d p [ n ] - это значение, которое все еще необходимо по крайней мере, поэтому вы можете обнаружить, что массив необходимо пройти по крайней мере несколько раз,

(x - dp [n]) / sum [n] + ((x - dp [n])% sum [n]> 0) (x-dp [n]) / sum [n] + ((x- dp [n]) \% sum [n]> 0)( х-d p [ n ] ) / s u m [ n ]+( ( х-d p [ n ] ) % s u m [ n ]>0 ) и, наконец, разделите оставшиеся числа на два.

Код

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int>pii;
const int MAXN=2e5+5;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
ll dp[MAXN];
ll a[MAXN];
int main()
{
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        int n,m;
        cin>>n>>m;
        ll sum=0;
        dp[0]=-1e18;
        for(int i=1;i<=n;i++)
        {
    
    
            cin>>a[i];
            sum+=a[i];
            dp[i]=max(sum,dp[i-1]);
        }
        while(m--)
        {
    
    
            ll x;
            cin>>x;
            if(dp[n]>=x)
            {
    
    
                int ans=lower_bound(dp+1,dp+1+n,x)-dp;
                printf("%d ",ans-1);
                continue;
            }
            if(sum<=0)
            {
    
    
                printf("-1 ");
                continue;
            }
            ll d=x-dp[n];
            ll p=(d+sum-1)/sum;
            x-=p*sum;
            ll ans=lower_bound(dp+1,dp+1+n,x)-dp+p*n-1;
            printf("%lld ",ans);
        }
        cout<<endl;
    }
}

рекомендация

отblog.csdn.net/weixin_45755679/article/details/113852450