Заголовок:
Дайте массив 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;
}
}