加载中...

AT_arc137_b [ARC137B] Count 1's 题解

题目传送门

解题思路

假设我们能得到的最大的分数是 \(maxx\),最小的分数是 \(minx\),我们的可能的种类就是 \(maxx-minx+1\),因为这一区域的分数都是可以做到的。而之所以如此,是因为每增加或减少一个数字,就只会改变一个 \(0\)\(1\),所以这一区间的分数都可以拿到。

于是,问题就成为了让我们求最大分数和最小分数。

我们再用 \(b\) 数组记录当前改变会对分数产生的影响,\(maxn\) 代表当时所能得到的最大分数,\(minn\) 同理。

所以,当:

  • \(a_i\) 等于 \(1\) 时,我们将 \(b_i\) 设为 \(-1\)。因为将其反转后分数会减一。

  • \(a_i\) 等于 \(0\) 时,我们将 \(b_i\) 设为 \(1\)。因为将其反转后分数会加一。

此时,我们再给 \(b\) 取前缀和,这时数组 \(b\) 就表示从开头到当前节点的所有改变造成的影响。

我们就可以从一枚举,每次更新各个变量的数值。

代码

#include<bits/stdc++.h>
using namespace std;

int a[300005],b[300005];

int main(){
	int n,maxx=0,minx=0,maxn=0,minn=0;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i],b[i]=b[i-1]+(a[i]==0?1:-1);
	for(int i=1;i<=n;i++){
		maxx=max(maxx,b[i]-minn),
		minx=min(minx,b[i]-maxn);
		maxn=max(maxn,b[i]),
		minn=min(minn,b[i]);
	}
	cout<<maxx-minx+1;
	return 0;
}


posted @ 2025-10-06 14:06  碎碎念的女巫  阅读(7)  评论(0)    收藏  举报