回旋加速器

前言:

追着单调队列来的,写完发现题解的其他技巧蚌埠住了。

正题:

题目传送门

我们可以先对每个加速腔处理,将 eidi(以下称为 di)作为从 ii+1 的成本。因为我是单调队列的做法,显然难以处理环,于是可以断环成链,再做观察。

题目要求绕环一周,断成链后即为从 i 出发到达 i+n。即要求对于 k[i,i+n1] 满足:

j=ikdj0

因此我们可以先处理成前缀和。设:

si=j=1idi

这样,条件就变成了对于 k[i,i+n1] 满足:

sksi10

然后发现,只要尝试 [i,i+n1]smin 是否满足条件,就可以得出答案。于是就可以用单调队列维护最小值啦!至于要求编号最小的,可以从 1 递推至 n,第一个满足条件的即为编号最小的。若递推至 n 之后仍然不满足条件,即为无解,输出Failed即可。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define TP template<typename T>
#define TP_ template<typename T,typename ... T_>
TP void read(T &x)
{
	x=0;int f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
	x*=f;
}
TP_ void read(T &x,T_&...y){read(x);read(y...);}
TP void write(T x){if(x<0){putchar('-'),x=-x;}if(x>9)write(x/10);putchar(48+x%10);}
TP void writeln(T &x){write(x);puts("");}
TP void writesp(T &x){write(x);putchar(' ');}
TP_ void writeln(const T &x,T_ &...y){writesp(x);writeln(y...);}
typedef long long LL;
constexpr int N=1e6+5;
constexpr int inf=1e9;
LL s[N<<1];
LL d[N<<1];
int l,r,q[N<<1];
int main()
{
	int T;read(T);
	while(T--)
	{
		int n;read(n);
		for(int i=1,x;i<=n;i++)
			read(x),d[i]=x;
		for(int i=1,x;i<=n;i++)
			read(x),d[i]-=x,d[i+n]=d[i];
		for(int i=1;i<=n*2;i++)//先处理为前缀和
			s[i]=s[i-1]+d[i];
		l=1;r=0;q[l]=0;
		for(int i=1;i<=n;i++)//将1~n的范围提前处理
		{
			while(l<=r&&s[q[r]]>=s[i])r--;
			q[++r]=i;
		}
		bool success=0;
		for(int i=1;i<=n;i++)
		{
			while(l<=r&&q[l]<i)l++;//使队列中始终只有i~i+n-1的范围
			if(s[q[l]]>=s[i-1])
			{
				writeln(i);//第一次满足条件即为最小的编号
				success=1;//记录是否有答案
				break;//直接跳出
			}
			while(l<=r&&s[q[r]]>=s[i+n])r--;
			q[++r]=i+n;
		}
		if(!success)puts("Failed!");//没答案就输出Falied
	}
	return 0;
}
posted @   wmtl_lofty  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示