Eugene and an array

一道看似小学生的题,搞了我几个小时…

首先思路就有两种:

Ⅰ . 找 和 为 0 的 b a d 子 串 , 再 用 n ∗ ( n + 1 ) / 2 − b a d 子 串 得 到 答 案 Ⅰ.找和为0的bad子串,再用n*(n+1)/2-bad子串得到答案 .0badn(n+1)/2bad

Ⅱ . 找 和 不 为 0 的 g o o d 子 串 Ⅱ.找和不为0的good子串 .0good

如果你选择找bad子串就很麻烦了。(为什么呢?自己去试一试吧,不好说。)

这里找good子串,枚举每一个数作为区间的右端点。

那 么 往 左 找 一 个 前 缀 和 为 0 的 左 端 点 , 答 案 贡 献 就 是 i − l + 1 那么往左找一个前缀和为0的左端点,答案贡献就是i-l+1 0il+1

特 殊 的 , 对 于 第 一 个 前 缀 和 为 0 的 要 特 判 。 特殊的,对于第一个前缀和为0的要特判。 0

#include 
using namespace std;
typedef long long ll;
const int maxn=2e5+9;
ll n,a[maxn],sumn,ans,L=0;
mapm;
int main()
{
	cin>>n;
	int flag=0;
	m[0]=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		sumn+=a[i];
		if(m[sumn])	L=max(L,m[sumn]+1);
		else if(sumn==0)//特判,也要更新 
			L=max(L,(ll)1);
		ans+=i-L;
		m[sumn]=i;
	}
	cout<

你可能感兴趣的:(CF刷题计划)