CF1778D题解

显然,我们可以先忽略两个串已经一样的部分,只考虑剩下不一样的部分,然后我们就可以将它抽象成一个链上游走问题。我们记 \(g_i\) 为从第 \(i-1\) 个到第 \(i\) 个点的期望步数,此时 \(g_1=1\)。且 \(g\) 满足:

\[g_i=\frac{n}{n-i}+\frac{i \cdot g_{i-1}}{n-i} \]

这时令 \(m=n-\sum \limits_{i=1}^{n}{[a_i = b_i]}\),所以根据期望的线性性,答案即为 \(\sum \limits_{i=1}^{m}{g_i}\)

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+10;
const int mod=998244353;
inline int read(){
	int f=1,w=0;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')    f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		w=(w<<1)+(w<<3)+(c^48);
		c=getchar();
	}
	return f*w;
}
int quickpow(int x,int p){
	int ans=1;
	while(p){
		if(p&1){
			ans=ans*x%mod;
		}
		x=x*x%mod;
		p>>=1;
	}
	return ans;
}
int inv(int x){
	return quickpow(x,mod-2)%mod;
}
int g[N];
int t;
int n;
signed main(){
	t=read();
	while(t--){
		n=read();
		string s1,s2;
		cin>>s1>>s2;
		int s=0;
		for(int i=0;i<n;i++){
			if(s1[i]==s2[i])	s++;
		}
		if(s==n){
			printf("0\n");
			continue;
		}
		g[0]=1;
		for(int i=1;i<n;i++){
			g[i]=((n*inv(n-i))%mod+((i*g[i-1])%mod*inv(n-i)%mod))%mod;
		}	
		int ans=0;
		for(int i=s;i<n;i++){
			ans=(g[i]+ans)%mod;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

posted @ 2023-09-08 09:45  OIer_xxx2022  阅读(67)  评论(0)    收藏  举报