Codeforces 1333 C. Eugene and an array

在这里插入图片描述

题意:

给定一个长度为 n n 的数组 a a ,问这个数组 a a 中有多少子数组是好数组,子数组的定义为: 把一个数组前面删去 0 0 个或全部元素,后面删去 0 0 个或全部元素得到的数组就是原数组的子数组。
子数组的定义为:

  • 把一个数组前面删去 0 0 个或全部元素,后面删去 0 0 个或全部元素得到的数组就是原数组的子数组

好数组的定义为:

  • 对于数组a的每个子数组b都满足 s u m b 0 sum{b}≠0 则数组a就是个好数组 。

所以我们在处理某个元素 a a 时,只看以 a a 为右边界的子数组, r = i r=i i i 位置开始往左寻找,直到将和为 0 0 的子数组包含进来后停止。这时包含这个数组是不能选择的,对于每一个右端点数组元素他的子数组个数是 i i ,我们找到他和为 0 0 最近左端点的位置然后减去这个长度即可。

AC代码:


const int N = 2e5 + 10;
int n, m;
int a[N];
map<ll, ll> vis;
ll ans, sum, now;

int main()
{
	sd(n);
	rep(i, 1, n)
		sd(a[i]);
	vis[0] = 0;
	ans = 0;
	sum = 0;
	now = 0;
	rep(i, 1, n)
	{
		sum += a[i];
		if (vis.count(sum) == 1)		  //前缀和为0的时候
			now = max(now, vis[sum] + 1); //找到上一个前缀和为0的位置
		vis[sum] = i;
		ans += i - now;
	}
	pld(ans);
	return 0;
}

发布了786 篇原创文章 · 获赞 460 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/qq_43627087/article/details/105402267