[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();
    }
}

相关文章:

  • 2021-12-14
  • 2022-12-23
  • 2021-12-03
  • 2021-06-11
  • 2021-08-16
  • 2022-12-23
  • 2022-12-23
  • 2021-12-03
猜你喜欢
  • 2022-02-27
  • 2021-08-07
  • 2022-12-23
  • 2021-11-25
  • 2022-02-28
  • 2022-02-22
  • 2021-06-17
相关资源
相似解决方案