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;
}

 

posted @ 2020-07-09 01:02  一个只会爆零的小菜鸡  阅读(281)  评论(0编辑  收藏  举报