【USACO2021 Lonely Photo】题解

题目

Farmer John has recently acquired N new cows (3≤N≤5×105), each of whose breed is either Guernsey or Holstein.

The cows are currently standing in a line, and Farmer John wants take a photo of every sequence of three or more consecutive cows. However, he doesn't want to take a photo in which there is exactly one cow whose breed is Guernsey or exactly one cow whose breed is Holstein --- he reckons this singular cow would feel isolated and self-conscious. After taking a photo of every sequence of three or more cows, he throws out all of these so-called "lonely" photos, in which there is exactly one Guernsey or exactly one Holstein.

Given the lineup of cows, please help Farmer John determine how many lonely photos he will throw out. Two photos are different if they start or end at different cows in the lineup.

Farmer John 最近购入了 N 头新的奶牛(3≤N≤5×105),每头奶牛的品种是更赛牛(Guernsey)或荷斯坦牛(Holstein)之一。

奶牛目前排成一排,Farmer John 想要为每个连续不少于三头奶牛的序列拍摄一张照片。 然而,他不想拍摄这样的照片,其中只有一头牛的品种是更赛牛,或者只有一头牛的品种是荷斯坦牛——他认为这头奇特的牛会感到孤立和不自然。 在为每个连续不少于三头奶牛的序列拍摄了一张照片后,他把所有「孤独的」照片,即其中只有一头更赛牛或荷斯坦奶牛的照片,都扔掉了。

给定奶牛的排列方式,请帮助 Farmer John 求出他会扔掉多少张孤独的照片。如果两张照片以不同的奶牛开始或结束,则认为它们是不同的。

思路

我们可以考虑每一头奶牛作为孤独的奶牛对照片数量的贡献。

于是我们可以预处理每只奶牛向左和向右与自己不同种类奶牛的连续长度,最后统计即可。

总结

对于此类题目,我们可以对每只奶牛分别考虑对答案的贡献,通过预处理来求出答案。

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 500010
int n, m, i, j, k; 
int l[N], r[N], ans; 
char a[N]; 

signed main()
{
	scanf("%d%s", &n, a+1); 
	for(i=1, k=0; i<=n; ++i)
		if(a[i]==a[i-1]) l[i]=0, ++k; 
		else l[i]=k, k=1; 
	for(i=n, k=0; i>=1; --i)
	{
		if(a[i]==a[i+1]) r[i]=0, ++k; 
		else r[i]=k, k=1; 
	}
	for(i=1; i<=n; ++i)
	{
		if(l[i]&&r[i]) ans+=l[i]*r[i]; 
		if(l[i]>=2) ans+=l[i]-1; 
		if(r[i]>=2) ans+=r[i]-1; 
	}
	printf("%lld", ans); 
	return 0;
}
posted @ 2021-12-21 17:33  zhangtingxi  阅读(741)  评论(2编辑  收藏  举报