abc 171 F - Strivore(排列组合)
题目链接: F - Strivore
题意:
求出在一个字符串s中插入n个小写字母,有多少不同的结果。
思路:
在字符串 s 中插入 n 个小写字母,就相当于在 n+s.length 个格子里面填入小写字母,要求其存在为 s 的子序列(不一定要连续)。
先确定 s 第一个字母所在的位置,假设在位置 i 处,(0< i <=n+1)i 前面的空格每一个都有26种情况,总共 \(26^{i-1}\)种情况,i 后面的空格,先选 s.length-1 各格子放入 s 的其他字母,有\(C_{k-i}^{len-1}\)种方法,然后每个 s 串字母后面不选相同的,用于去重,有 \(25^{k-i-len+1} \) 种情况。
对应公式为:
\(\sum_{i=1}^k 26^{i-1}\times C_{k-i}^{len-1}\times25^{k-i-len+1}\) (len=s.length,k=len+n)
AC代码
#include <bits/stdc++.h> using namespace std; #define sint(a) scanf("%d",&a) #define sint2(a,b) scanf("%d %d",&a,&b) #define sll(a) scanf("%lld",&a) #define sll2(a,b) scanf("%lld %lld",&a,&b) #define mem(a,i) memset(a,i,sizeof(a)) #define pb push_back #define ll long long #define lson node<<1 #define rson (node<<1)+1 const int maxn=3e6+10; const ll mod=1e9+7; const double pi=acos(-1); ll qpow(ll a,ll n) { ll b=1; while(n) { if(n&1) b=(b*a)%mod; a=a*a%mod; n>>=1; } return b; } ll ji[maxn]; void init() { ji[0]=1; for(int i=1;i<maxn;i++) ji[i]=ji[i-1]*i%mod; } ll c(ll a,ll n) { return ji[n]*qpow(ji[a],mod-2)%mod*qpow(ji[n-a],mod-2)%mod; } int main() { init(); ll n; string s; cin>>n>>s; ll len=s.length(); ll k=len+n; ll ans=0; for(int i=1;i<=k-len+1;i++) { ans=(ans+qpow(26,i-1)*qpow(25,k-i-len+1)%mod*c(len-1,k-i)%mod)%mod; } cout<<ans; return 0; }