CF1178B题解

CF1178B题解

思路:前缀和+后缀和+乘法原理

首先建立两个数组:\(a\)\(b\)\(a\) 用来记录第 \(i\) 个字符前面有几个“vv”, \(b\) 用来记录第 \(i\) 个字符后面有几个“vv”。

那就很明了,用两个循环解决!如果第 \(i\) 个字符是 \(v\),第 \(i-1\)\(i+1\))个也是,那前(后)缀就加 \(1\)

接下来求出来了前后缀,到了重点部分:累加答案。

其实也挺简单的,就是再把整个字符串重新遍历一遍,要是找到一个 \(o\)(设这个 \(o\) 在字符串的第 \(i\) 个位置),则答案 \(ans\) 就加 \(a[i]\times b[i]\)

这时有人就会问为啥加的是 \(a[i]\times b[i]\)

这就要涉及小学的加乘原理了,这里用的是乘法原理:

前面有 \(a[i]\) 对,后面有 \(b[i]\) 对,总共就有 \(a[i]\times b[i]\) 对。

总结

  1. long long,不开 long long 见祖宗。
  2. 前后缀和。
  3. 乘法原理。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
string s;
long long a[1000005],b[1000005],ans;
//a数组记录前缀和:前面有几个"vv"。 
//b数组记录后缀和:后面有几个"vv"。 
int main(){
	cin>>s;
	int len=s.size();
	for(int i=1; i<len; i++){//记录前缀。 
		if(s[i]=='v'&&s[i-1]=='v') a[i]++;//多了一对"vv"。 
		a[i]+=a[i-1];
	} 
	for(int i=len-1; i>=1; i--){//记录后缀。 
		if(s[i]=='v'&&s[i+1]=='v') b[i]++;//多了一对"vv"。 
		b[i]+=b[i+1]; 
	}
	for(int i=0; i<len; i++)//最后一次遍历求答案,找o,然后用乘法原理累加答案。 
		if(s[i]=='o')//找到一个o 
			ans+=b[i]*a[i];
			//乘法原理。 
			//前面有a[i]对,后面有b[i]对,总共就有a[i]*b[i]对。
	printf("%lld",ans); 
	return 0;
}
posted @ 2025-01-29 15:27  naroto2022  阅读(38)  评论(0)    收藏  举报