回旋加速器
前言:
追着单调队列来的,写完发现题解的其他技巧蚌埠住了。
正题:
我们可以先对每个加速腔处理,将
题目要求绕环一周,断成链后即为从
因此我们可以先处理成前缀和。设:
这样,条件就变成了对于
然后发现,只要尝试 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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现