Codeforces Round #848 (Div. 2) D - Flexible String Revisit
题意:给定两个 题意:给定两个 题意:给定两个 01 01 01 字符串 字符串 字符串 a a a 和 和 和 b b b , 每次操作可选择字符串 每次操作可选择字符串 每次操作可选择字符串 a a a 上的数字反转 上的数字反转 上的数字反转, 即: 0 即:0 即:0 − > 1 ->1 −>1 或者 1 1 1 − > 0 。 -> 0。 −>0。 每个位上操作的 每个位上操作的 每个位上操作的 概率相同 即每个位上操作的概率都是 1 / n 即每个位上操作的概率都是1/n 即每个位上操作的概率都是1/n , 现问将字符串 a 翻转成 b 的期望步数是多少。 现问将字符串a翻转成b的期望步数是多少。 现问将字符串a翻转成b的期望步数是多少。
公式推导:
公式推导:
公式推导:
参考代码:
参考代码:
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#pragma GCC optimize(3)
typedef pair<int,int>PII;
#define pb push_back
const int N = 1e6+10;
const int mod = 998244353;
int inv[N];
int c[N],d[N];//kx+b
int qmi(int a,int b){
int res=1;
while(b){
if(b&1)res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
void cf(){
int sum=0;
int n;
cin>>n;
string a,b;
cin>>a>>b;
for(int i=0;i<a.size();i++){
if(a[i]!=b[i])sum++;
}
c[0]=d[0]=d[1]=0;
c[1]=1;
for(int i=2;i<=n;i++){
c[i] = (c[i-1]*n-c[i-2]*(i-1))%mod*inv[n-i+1]%mod;
d[i] = (d[i-1]*n-d[i-2]*(i-1)-n)%mod*inv[n-i+1]%mod;
}
int dp1=(1+d[n-1]-d[n])*qmi(c[n]-c[n-1],mod-2)%mod;
int ans=(c[sum]*dp1+d[sum])%mod;
if(ans<0)ans+=mod;
cout<<ans<<endl;
return ;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
inv[1]=1;
for(int i=2;i<N;i++){//O(n)线性求区间逆元
inv[i]=mod-mod/i*inv[mod%i]%mod;
}
int _=1;
cin>>_;
while(_--){
cf();
}
return 0;
}