[CF1490G] Old Floppy Drive
Description
给定序列 (a) ,把 (a) 反复制成一个无限序列,然后给 (m) 个询问,每次给定 (x) ,问 (a) 的第一个前缀和达到 (x) 的下标。
Solution
因为这里的要求是达到,所以前缀和序列可以求个 premax
然后首先我们找到需要多少个完整序列,具体地,将目标 x 减去最大前缀和 maxpre 除以 sum 上取整
然后再取过 premax 的 presum 序列上二分,找到第一个大于等于剩余量的位置即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
int n, m;
cin >> n >> m;
vector<int> s(n + 2);
for (int i = 1; i <= n; i++)
{
cin >> s[i];
s[i] += s[i - 1];
}
int sum = s[n];
for (int i = 1; i <= n; i++)
{
s[i] = max(s[i], s[i - 1]);
}
int maxpre = s[n];
for (int i = 1; i <= m; i++)
{
int x;
cin >> x;
if (maxpre >= x)
{
int pos = lower_bound(&s[1], &s[n + 1], x) - &s[0];
cout << pos - 1 << " ";
}
else if (sum <= 0)
{
cout << -1 << " ";
}
else
{
int times = (x - maxpre + sum - 1) / sum;
x -= times * sum;
int pos = lower_bound(&s[1], &s[n + 1], x) - &s[0];
cout << pos + times * n - 1 << " ";
}
}
cout << endl;
}
signed main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
solve();
}
}