题解:P11963 [GESP202503 六级] 环线
DeepSleep_Zzz · · 题解
begin
P11963 [GESP202503 六级] 环线
前言(渺小)
考试的时候打了一个超级无敌大歪解,个人认为漏洞百出,但是还是成功的骗到了
考后看到标签后恍然大悟,造就了这篇题解。
另:不会单调队列的可以去看看 P1886 滑动窗口 /【模板】单调队列。
思路
我们简化一下题目:截取一个长度
那么众所周知,如果要让和最大,那么减掉的就越少越好。
所以我们可以先求出破环成链后的
针对上述思路,单调队列简直再合适不过了。
Code
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const ll N=4e5+10;
ll n,a[N],sum[N],q[N],head=1,tail,ans=-1e10;
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
// 破环成链
for (ll i=1;i<=n;i++) cin>>a[i],a[i+n]=a[i];
// 前缀和
for (ll i=1;i<=n*2;i++) sum[i]=sum[i-1]+a[i];
// 单调队列
for (ll i=1;i<=n*2;i++)
{
while (head<=tail && i-q[head]>n) head++; // 确保区间长度合法
while (head<=tail && sum[q[tail]]>=sum[i]) tail--; // 构造递增队列的
ans=max(ans,sum[i]-sum[q[head]]); // 取最大值
q[++tail]=i; // 扔进去
}
cout<<ans;
return 0;
}
end