专栏文章
题解:P11963 [GESP202503 六级] 环线
P11963题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miptsrt0
- 此快照首次捕获于
- 2025/12/03 17:49 3 个月前
- 此快照最后确认于
- 2025/12/03 17:49 3 个月前
解析
在 组成的环中,选取最大的连续和。
遇到环,就先破环成链,为了减少分类讨论,我们将链复制一条,也就是要 ,此时问题转化成了,对 时求最大的 ,首先进行前缀和,令 ,则就是要求 的最大值,此时直接枚举 ,时间复杂度为 ,所以要优化。
于是再定义一个数组 表示在区间 的最小 值,这个类似滑动窗口,可以使用单调队列来完成。于是最终答案就是 ,时间复杂度为 。
代码
注意开
CPPlong long。#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 4e5+1;
ll n, a[N], sum[N], b[N], ans=-2e18;
deque<ll> q;
// b[i]: [i-n+1, i-1]中最小的sum[i]
int main(){
cin>>n;
for(int i=1;i<=n;i++){cin>>a[i]; a[i+n]=a[i];}
for(int i=1;i<=n*2;i++) sum[i] = sum[i-1] + a[i];
for(int i=1;i<=n*2;i++){
while(!q.empty() && q.front() <= i-n) q.pop_front();
while(!q.empty() && sum[q.back()] >= sum[i]) q.pop_back();
q.push_back(i);
b[i] = sum[q.front()];
}
for(int i=1;i<=n*2;i++) ans = max(ans, sum[i] - b[i-1]);
cout << ans;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...