题意: 给定一个字符串
,问插入
个字符后可以形成多少个不同的字符串,答案对
取模。
题解: 设字符串
长度为
,当插入了
个字符后长度变为
,故我们可以枚举字符串
的
个字符位置。
- 枚举 为字符串 中 这个字符(最后一个字符)的位置,那么之后的 个字符每个都有 个选择,即 种。
- 那么对于前面 个字符,(第 个字符已经确定),我们先选择其中 个位置作为 的前 个字符,则剩下的 个则只有25种选择。至于这 个只有25种就是如下图中 ^ 的这种字符,因为如果在 和 间的 这个位置出现了 ,那么相当于将这个 的位置选择在了 ,后面的又是根据 来选择了。
- 换种方式理解 :这个过程可以看出 的状态转移。那么我们考虑 中最后一个字符 的位置,由 可知道当确定了 的位置后,其后面的所有字符有 种选择,所以当我们在 和 中插入了一个和 相同的字符,相当于将 的位置前移了,那么就是另一种情况了。所以枚举的前 个字符中的 个字符有 种情况。
戳我进官方题解
下图是官方题解图:
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
ll fac[N], inv[N];
char s[N];
int k;
ll qp(ll a, ll b) {
ll res = 1;
while(b) {
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void init() {
fac[0] = fac[1] = 1;
for(int i = 2; i < N; i++) fac[i] = fac[i - 1] * i % mod;
inv[N - 1] = qp(fac[N - 1], mod - 2);
for(int i = N - 2; i >= 0; i--) inv[i] = inv[i + 1] * (i + 1) % mod;
}
ll C(ll a, ll b) {
if(b > a) return 0ll;
return fac[a] * inv[b] % mod * inv[a - b] % mod;
}
ll add(ll a, ll b) {
return (a + b) % mod;
}
int main()
{
init();
scanf("%d", &k);
scanf("%s", s);
ll res = 0;
int len = strlen(s);
for(int i = len; i <= k + len; i++) //枚举前i个字符为S的所在地,即第i个位置是字符s[len-1]的所在地
res = add(res, C(i - 1, len - 1) * qp(25ll, i - len) % mod * qp(26ll, k + len - i) % mod);
printf("%lld\n", res);
return 0;
}