Codeforces Round #702 (Div. 3)

比赛链接

Codeforces Round #702 (Div. 3)

给定序列 \(a\) ,把 \(a\) 反复制成一个无限序列,然后给 \(m\) 个询问,每次给定 \(x\) ,问 \(a\) 的第一个前缀和达到 \(x\) 的下标。
\( a_{i}, x \leq 10^{9} \\ n, m \leq 2 * 10^{5} \)

解题思路

二分

注意,本题要求的是达到而不是相等,不妨先求出一个循环中最大的前缀和 \(mx\),设前面进行了 \(t\) 轮循环,下一轮循环达到 \(x\),则有 \(mx+t\times s[n]\geq x\),则 \(t=\left \lceil \frac{x-mx}{s[n]} \right \rceil\),则在下一轮中找出满足条件的最小的下标即可。另外,需要特判第一轮的情况,然后如果第一轮结束后 \(s[n]\leq 0\),则肯定无法达到 \(x\)

这里有一个小技巧:求满足条件的最小下标时可以先求出前缀最值,再lower_bound求解

  • 时间复杂度:\(O(mlogn)\)

代码

// Problem: G. Old Floppy Drive
// Contest: Codeforces - Codeforces Round #702 (Div. 3)
// URL: https://codeforces.com/contest/1490/problem/G
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=2e5+5;
int t,n,m,a[N],s[N];
signed main()
{
    for(cin>>t;t;t--)
    {
    	cin>>n>>m;
    	s[0]=0;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    		s[i]=s[i-1]+a[i];
    	}
    	int sum=s[n];
    	for(int i=2;i<=n;i++)s[i]=max(s[i],s[i-1]);
    	int mx=s[n];
    	while(m--)
    	{
    		int x;
    		cin>>x;
    		if(mx>=x)
    		{
    			cout<<lower_bound(s+1,s+1+n,x)-s-1<<' ';
    			continue;
    		}
    		if(sum<=0)cout<<-1<<' ';
    		else
    		{
    			int t=(x-mx+sum-1)/sum;
    			int res=t*n-1;
    			x-=t*sum;
    			int pos=lower_bound(s+1,s+1+n,x)-s;
    			res+=pos;
    			cout<<res<<' ';
    		}
    	}
    	puts("");
    }
    return 0;
}
posted @ 2022-06-01 00:25  zyy2001  阅读(22)  评论(0编辑  收藏  举报