开始想到dp去了…
还是考虑问题太片面了
取 对 立 事 件 , 计 算 不 合 法 的 子 串 数 量 取对立事件,计算不合法的子串数量 取对立事件,计算不合法的子串数量
不 合 法 子 串 只 可 能 是 形 如 不合法子串只可能是形如 不合法子串只可能是形如
A + B B B B , B + A A A A , A A A A + B , B B B B + A 这 样 的 A+BBBB,B+AAAA,AAAA+B,BBBB+A这样的 A+BBBB,B+AAAA,AAAA+B,BBBB+A这样的
因 为 再 加 任 何 的 A 或 者 B , 都 会 使 得 相 邻 的 两 个 A 间 是 回 文 , 相 邻 的 B 间 是 回 文 因为再加任何的A或者B,都会使得相邻的两个A间是回文,相邻的B间是回文 因为再加任何的A或者B,都会使得相邻的两个A间是回文,相邻的B间是回文
那 么 直 接 统 计 即 可 那么直接统计即可 那么直接统计即可
//定义dp[i]是以i结尾的最长序列
//若当前字母是'A',如果上一个字母是'A',那么dp[i]=dp[i-1]
//如果上一个字母是'B',那么dp[i]=dp[last] last指最早出现的字母'A'
#include
using namespace std;
#define int long long
int n,ans,dp[300009];
char a[300009];
signed main()
{
cin >> n >> (a+1);
int pre=1;
for(int i=2;i<=n;i++)
{
if( a[i]!=a[i-1] )
{
ans+=(i-pre);//i-pre是前面连续的字母长
//这里是计算形如AAAAAB,BBBBBA
pre=i;
}
else if(pre!=1) ans++;
//这里计算形如BAAAAA,ABBBBB
//为啥pre!=1?当pre=1说明前面都是一种字母,所以不能加上答案
}
cout << n*(n-1)/2-ans;
}