Codeforces 578D
# Codeforces 578D
出题人给的题解像💩一样
# 非DP做法1
为什么网上的题解都没有给出"仅当子串为ababab交替出现时会重复计算"这一解题关键的证明/思路?估计是我太菜了。
对于串,可以把连续相同的字符分在同一组,设组数为。
对于某一个组,我们考虑从其中去除一个字符,得到新的字符串,再向其中加入一个字符得到新的串,有种。由于向组中任意一个位置添加字符得到的串都是相同的,要减去重复计算的数,因此有
总的答案即为
以下证明完全是自找苦吃,还不一定正确
下面考虑特殊字符串导致重复计算的情况。
对于一个串,将省略部分分别记为。
从中分别去掉字符得到,然后向中分别添加一个新字符得到,若重复计算,说明,
若,则
- (无证明)仅当循环时
若,则
显然字符或被添加到中时,由于不存在有限长的字符串使得(或因为),因此定有,因此忽略,考虑子串,被省略部分记为。记。
同理,当字符被添加进中时,不存在有限长的字符串使得
- 若,显然
- 若,不存在使
- 若,唯一可行的解为。易得为循环
- 若,不存在使
结论:当且仅当字符串交替出现(ab...a或ab....ab)时会重复计算,且只会被重复计算1次。
最终答案
下面是从大佬那copy来的代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
int n,m,same; char c1,c2;
signed main(){
scanf("%d%d",&n,&m);
while (!isalpha(c1)) c1=getchar();
rr long long ans=n*(m-1);
for(rr int i=1;i<n;++i){
rr char c=getchar();
same=(c==c2)?same+1:0;
if(c!=c1) ans+=n*(m-1)-same-1;
c2=c1; c1=c;
}
return !printf("%lld",ans);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
上次更新: 2021/02/24, 03:37:30