C. Eugene and an array(思维题)

const int N = 4e5 + 5;
int t;
ll a[N], sum[N];
int main()//取得所有的子串==每个点的全部向右延伸或全部向左延伸
{
	ll n;
	while (cin >> n)
	{
		f(i, 1, n)
		{
			scanf("%lld", &a[i]);
			sum[i] = sum[i - 1] + a[i];
		}
		map<ll, int> mp;//某个前缀重复出现,那么两次出现的区间和为0
		mp[(ll)0] = 0;
		ll ans = 0;
		int mxl =0;//无阻碍
		f(i, 1, n)//枚举每个点的向左延伸,看看能延伸几个,小于mxl的无法延伸
		{
			if (mp.count(sum[i]))mxl = max(mp[sum[i]]+1,mxl);//维护最右的阻碍点
			//debug(mxl);
			mp[sum[i]] = i;
			ans += i - mxl;
		}
		cout << ans << endl;
	}
	return 0;
}

你可能感兴趣的:(Codeforces,pupil)