计蒜客 A2232.程序设计:蒜厂年会-单调队列(双端队列(STL deque)实现)滑窗维护最小前缀和

时间:2023-03-10 07:10:14
计蒜客 A2232.程序设计:蒜厂年会-单调队列(双端队列(STL deque)实现)滑窗维护最小前缀和
问答问题反馈
只看题面
  • 16.79%
  • 1000ms
  • 262144K

在蒜厂年会上有一个抽奖,在一个环形的桌子上,有 nn 个纸团,每个纸团上写一个数字,表示你可以获得多少蒜币。但是这个游戏比较坑,里面竟然有负数,表示你要支付多少蒜币。因为这些数字都是可见的,所以大家都是不会出现的赔的情况。

游戏规则:每人只能抓一次,只能抓取一段连续的纸团,所有纸团上的数字和就是你可以获得的蒜币。

蒜头君作为蒜厂的一员在想,我怎么可以获得最多的蒜币呢?最多能获取多少蒜币呢?

因为年会是发奖,那么一定有大于 00 的纸团。

输入格式

第一行输入一个整数 nn,表示有 nn 个纸团。

第二行输入输入 nn 个整数 a_iai​,表示每个纸团上面写的数字(这些纸团的输入顺序就是环形桌上纸团的摆放顺序)。

输出格式

输出一个整数,表示蒜头君最多能获取多少蒜币。

数据范围

对于 30\%30% 的数据:1 \le n \le 10^2,-10^3 \le a_i \le 10^31≤n≤102,−103≤ai​≤103。

对于 60\%60% 的数据:1 \le n \le 5 \times 10^3,-10^6 \le a_i \le 10^61≤n≤5×103,−106≤ai​≤106。

对于 100\%100% 的数据:1 \le n \le 10^5,-10^9 \le a_i \le 10^91≤n≤105,−109≤ai​≤109。

样例输入复制

3
1 -2 1

样例输出复制

2

题目来源

2019 蓝桥杯省赛 B 组模拟赛(一)

因为是环形的,所以前缀和算2倍长的。、

因为是连续的,所以直接遍历的时候,当前的前缀和-当前区间的最小的前缀和,就是最大的前缀和,单调队列滑窗实现,因为总长是固定的,但是我写了2倍长,所以要长度<=n,就没了。

思路队友想的。我是水的,我代码实现的时候,被怼的有点难过,哈哈,太菜了。

代码:

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=*1e5+;
const int inf=0x3f3f3f3f; int a[maxn];
ll pre[maxn],Min[maxn];
deque<ll> deq; int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
pre[i]=pre[i-]+a[i];
}
for(int i=n+;i<=*n;i++){
pre[i]=pre[i-]+a[i-n];
}
deq.push_back();
ll ans=;
for(int i=;i<=*n;i++){
while(i-deq.front()>n) deq.pop_front();
ans=max(ans,pre[i]-pre[deq.front()]);
while(deq.size()&&pre[deq.back()]>=pre[i])
deq.pop_back();
deq.push_back(i);
}
cout<<ans<<endl;
}