题目:
思路
正向考虑子串是否满足要求的判断条件设计比较困难,而逆向考虑不满足要求的子串的判断条件设计较为简单,不满足条件的子串为AB…B;BA…A;A…AB;B…BA这四种。只要在所有子串总数中减去这四种类型子串即可,字符数量大于2的所有子串的数量为n*(n-1)/2。
将相同字符段缩为一个整型变量,对于第一,二种类型,从第二个整型变量开始遍历,他们的和即为这两种子串的总数(取前一段的最后一个字符);第三,四种从第一个整型遍历到倒数第二个整型,他们的和就是这两种类型子串的总数(取后一段的第一个字符)此时AB,BA这种子串被重复计算,需要加上。
代码
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
const int maxn=3e5+5;
typedef long long ll;
ll n,count;
int note[maxn];
ll solve()
{
ll res=n*(n-1)/2;
for(int i=1;i<=count;i++)
res-=2*note[i];
res+=note[1]+note[count]+count-1;
return res;
}
int main()
{
scanf("%d",&n);
getchar();
char last,now;
scanf("%c",&last);
int num=1;
count=0;
for(int i=1;i<n;i++)
{
scanf("%c",&now);
if(now==last)
num++;
else
{
note[++count]=num;
num=1;
last=now;
}
}
note[++count]=num;
ll res=solve();
printf("%lld",res);
return 0;
}