CF1778D - Flexible String Revisit
CF1778D - Flexible String Revisit
https://codeforces.com/contest/1778/problem/D
题意
给出两个长度均为
每次随机将
问:第一次
思路
显然,我们只关心当前
用
转移方程:
显然,此转移方程存在环。 如何处理?
不妨从
当
可以改写成一般的线性递推式:
因为
由此不难发现,
注意到:
注意到分子的 $-1$ 是常数,他只应该作用在常数 $q$ 上。
也就是:
$p_i=\frac{p_{i-1}-p_{i-2}\times \frac{i-1}{n}}{1-\frac{i-1}{n}},q_i=\frac{q_{i-1}-q_{i-2}\times \frac{i-1}{n}-1}{1-\frac{i-1}{n}}$。
最后,答案就是
void Sol()
{
vector< pair<int,int> > dp(n+5);
dp[0] = {0, 0};
dp[1] = {1, 0};
for (int i=2; i<=n; i++)
{
int inv = Div(i-1, n);
// 递推 pi, qi
dp[i].first = Div(((dp[i-1].first-(dp[i-2].first*inv%MOD)+MOD)%MOD+MOD)%MOD, (1-inv+MOD)%MOD);
dp[i].second = Div(((dp[i-1].second-(dp[i-2].second*inv%MOD)+MOD)%MOD-1+MOD)%MOD, (1-inv+MOD)%MOD);
}
// 求解 f1
int p = (dp[n].first-dp[n-1].first+MOD)%MOD;
int q = (dp[n].second-dp[n-1].second+MOD)%MOD;
int t = Div((1-q+MOD)%MOD, p);
int cnt = 0;
for (int i=1; i<=n; i++)
cnt += (S[i] != T[i]);
int ans = (dp[cnt].first*t%MOD + dp[cnt].second)%MOD;
printf("%lld\n", ans);
}