题解 | #切圈圈#

切圈圈

https://ac.nowcoder.com/acm/problem/220554

题意:对于一个保证 i=1nai=0\sum\limits_{i=1}^{n} a_i=0 的序列 {an}\{a_n\},求划分出的最大段数使得每一段区间和均为 00

考虑前缀和,对于一个区间 [l,r][l,r],如果 sl1=srs_{l-1}=s_r 代表区间和为 00

sl1=a1+a2++al1s_{l-1}=a_1+a_2+\cdots+a_{l-1}

sr=a1+a2++ars_{r}=a_1+a_2+\cdots+a_{r}

srsl1=al++ar\therefore s_{r}-s_{l-1}=a_l+\cdots+a_r

sl1=sr\because s_{l-1}=s_r

al++ar=0\therefore a_l+\cdots+a_r=0,得证。

有了这个结论,我们只需要数出前缀和数组中的众数即可,等于是把每一段都划分成这个众数既为 sl1s_{l-1} 又为 srs_r

环形和整个序列和为零的性质保证了这样做的正确性。

#include<map>
#include<cstdio>
int init(){
	char c = getchar();
	int x = 0, f = 1;
	for (; c < '0' || c > '9'; c = getchar())
		if (c == '-') f = -1;
	for (; c >= '0' && c <= '9'; c = getchar())
		x = (x << 1) + (x << 3) + (c ^ 48);
	return x * f;
}
void print(int x){
	if (x < 0) x = -x, putchar('-');
	if (x > 9) print(x / 10);
	putchar(x % 10 + '0');
}
int mx(int x, int y){
	return x > y ? x : y;
}
std::map<int, int>map;
int main(){
	int T = init();
	while (T--) {
        map.clear();
		int n = init(), ans = 0, max = 0;
		while (n--) {
			ans += init();
			max = mx(max, ++map[ans]);
		}
		print(max), putchar('\n');
	}
}
全部评论

相关推荐

牛客小菜鸡66:boss里面,招人的叫老板,找工作的叫牛人
点赞 评论 收藏
分享
09-09 21:23
门头沟学院 Java
程序员牛肉:小牛肉来也! 主要就是没有实习经历。因为你的投递方向肯定是中小厂。在小厂中,很少会有公司愿意花钱培养你。因此会更加青睐有实习的同学。再加上你的学历比较差一点,所以找不到是正常的。 跟简历项目啥的已经没有大关系了,就是差一份实习。秋招和日常实习一起投递吧。
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务