题目链接
题意分析
怎么说呢 感觉这道题还是找规律套结论
首先 对于一个字符串 我们最直观的想法就是去掉一个字符 然后再在其余n个位置每个位置可以有m-1种字符插入
那么就存在n*(m-1)种方案
但是存在重复的
- 对于aaabbbccc这种存在一段连续相同字符的字符串 很显然 一段连续相同字符的话 我们只能算上一种
2.我们考虑这样一种字符串abababababab
abababababa_ → abababaababa_ → abababaababa
abababa_abab → abababa_ababa → abababaababa
abababababa_ → ababababbaba_ → ababababbaba
abababab_bab → abababab_baba → ababababbaba
对于一个长度为k的这样的字符串
第2个字符存在1个子串 第3个字符存在2个子串 ... 第k个字符存在k-1个子串
所以一共存在(frac{k(k-1)}{2})种重复情况
所以我们需要把这些也去除掉
CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define M 100080
using namespace std;
char s[M];
int n,m;
long long ans,k;
int main()
{
scanf("%d%d",&n,&m);
scanf("%s",s+1);
for(int i=1;i<=n;++i)
if(s[i]!=s[i-1]) ans+=(long long)n*(long long)(m-1);
k=1LL;
for(int i=2;i<=n;++i)
{
if(k==1)//这是起始的边界情况处理
{
if(s[i]!=s[i-1]) ++k;
}
else
{
if(s[i]==s[i-2]) ++k;//按照上述字符串的要求进行处理
else
{
ans-=k*(k-1)/2;
if(s[i]!=s[i-1]) k=2LL;//这是起始的边界情况
else k=1LL;
}
}
}
ans-=k*(k-1)/2;
printf("%lld
",ans);
return 0;
}