题目简述
给定一个只含 $v$ 和 $o$ 的字符串 $s$,求字符串中有多少个 $wow$(一个 $w$ 即为连续的两个 $v$)。
题目分析
考虑枚举每一个 $o$,设下标为 $i$,统计它左边和右边各有多少个 $w$,分别设为 $a_{i-1}$ 和 $b_{i+1}$,依据乘法原理,将它们乘起来即为答案,累加即可。
接下来,考虑怎么处理右边出 $w$ 的个数,$a_i$ 表示区间 $[1,i]$ 中有多少个 $w$,如果当前的 $s_i=o$,那么则从 $a_{i-1}$ 转移即可,如果当前 $s_i=v$,那要分两种情况:
- 如果 $s_{i-1}=o$,那么就组合不成 $w$,即 $a_i \leftarrow a_{i-1}$。
- 如果 $s_{i-1}=v$,那么 $s_i$ 就可以与 $s_{i-1}$ 组合成一个 $w$,即 $a_i \leftarrow a_{i-1}+1$。
知道了左边怎么处理,右边也同理,反着做就可以了。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define random(a,b) (rand()%(b-a+1)+a)
#define se second
#define fi first
#define pr pair<int,int>
#define pb push_back
#define ph push
#define ft front
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,a,b) for(int i=a;i>=b;i--)
#define mem(a,b) memset(a,b,sizeof a)
const int N=1e6+10;
char s[N];
int n;
ll a[N],b[N],ans;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>s+1;
n=strlen(s+1);
For(i,1,n) a[i]=a[i-1]+(s[i]=='v'&&s[i-1]=='v');
Rep(i,n,1) b[i]=b[i+1]+(s[i]=='v'&&s[i+1]=='v');
For(i,1,n)
{
if(s[i]=='o')
{
ans+=(ll)a[i-1]*b[i+1];
}
}
cout<<ans;
return 0;
}
标签:1178B,int,WOW,Codeforces,Factor,ll,define
From: https://www.cnblogs.com/zhuluoan/p/18198529