分析:
暴力会超时,可以用二分,构建两个数组,一个是a[i],作为前缀和数组,一个是f[i]表示第i个台阶之前的最大高度的台阶,然后每次二分来查找k,因为尽可能地走的多,所以查找右边界,最后输出对应的前缀和。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
signed main()
{
ios::sync_with_stdio(false),cin.tie(0);
int _;
cin>>_;
while(_--)
{
int n,q;
cin>>n>>q;
vector<int> a(n+1);
vector<int> f(n+1);
for(int i=1;i<=n;i++)
{
cin>>a[i];
f[i]=max(f[i-1],a[i]);
a[i]+=a[i-1];
}
while(q--)
{
int k;
cin>>k;
int l=1;
int r=n;
while(l<r)
{
int mid=l+r+1 >> 1;
if(f[mid]<=k) l=mid;
else r=mid-1;
}
if(f[l]<=k) cout<<a[l]<<' ';
else cout<<0<<' ';
}
cout<<'\n';
}
}