CF578D题解

LCS 为给定串的长度减一,考虑枚举一个区间 \([L,R]\),表示 \(S\)\(T\) 的长度为 \(L-1\) 的前缀完全相同以及长度为 \(n-R\) 的后缀完全相同,且没有比这个前缀和后缀更长的前缀和后缀。

可以发现对于一组 \([L,R]\),满足条件的串还需要满足 \(S[L+1,R]=T[L,R-1]\)\(S[L,R-1]=T[L+1,R]\)。证明显而易见。

对于两种情况分别讨论。因为两种情况没有区别,这里以 \(S[L+1,R]=T[L,R-1]\) 为例。

  1. \(2\leq R-L+1\)

可以发现,如果 \(S[L]=S[L+1]\),那么这个区间就失去了意义(出现了比 \(S[L-1]\)\(T[L-1]\) 更长的前缀),可以直接开润。

对于 \(T[R]\) 的讨论,只要让其不等于 \(S[R]\) 就好了。方案数 \(m-1\) 种。

  1. \(L=R\)

无论如何方案数一定是 \(m-1\)

需要注意的是,如果出现了 \(S[L+1,R]=T[L,R-1]\)\(S[L,R-1]=T[L+1,R]\) 同时满足的情况,需要减掉。

注意到这种情况满足 \(S[x-1]=T[x]=S[x+1]\)

例子:\(S=aba,T=bab\),基本上直接统计就好了。得到了一个 \(O(n^2)\) 的做法。

\(f[n]=[S[n]\neq S[n+1]],g[n]=[S[n-1]=S[n+1]]\),那么答案是:

\[\sum_{l=1}^{n-1}f[l](\sum_{r=l+1}^{n}m-1)+\sum_{r=2}^{n}f[r-1](\sum_{l=1}^{r-1}m-1)+(m-1)\times n-\sum_{l=1}^{n-2}f[l]\sum_{r=l+2}^{n}f[r-1]\times\prod_{x=l+1}^{r-1}g[x] \]

处理一下 \(f,g\),以及 \(g\) 的极长连续段,然后再处理一个 \(f\) 的前缀和就可以 \(O(n)\) 了。

#include<cstdio>
#include<cctype>
typedef unsigned ui;
const ui M=1e5+5;
ui n,m,f[M],g[M];unsigned long long S[M];char s[M];
signed main(){
	unsigned long long ans;
	scanf("%u%u%s",&n,&m,s+1);ans=1ull*n*(m-1);
	for(ui i=1;i<n;++i)f[i]=s[i]!=s[i+1],S[i]=S[i-1]+f[i];
	for(ui i=1;i<=n;++i)if(f[i])ans+=1ull*n*(m-1)-1;
	for(ui L(1),i=2;i<n;++i){
		if(s[i-1]==s[i+1]){
			if(f[i])ans-=S[i]-S[L];
		}
		else L=i;
	}
	printf("%llu",ans);
}
posted @ 2022-03-14 08:59  Prean  阅读(26)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};