Killer Names

HDU

The meaning of problems: first and last name from the name of two parts, each part containing n characters, and now the number of characters of the same name does not contain a total of m characters, find the first and last name. \ ((N, m <= 2000) \)

Analysis: As long as we determine the composition of the surname, you can find a number of well-known composition program we set up. \ (F [i] \) indicates the number of programs surname n characters of different characters i use content. repellent thinking, the same regimen comprises subtracting the total number of characters (scheme i n characters of the number of characters) scheme, can be obtained \ (F [i] \) of the expression.

\(f[i]=i^n-\sum_{j=1}^{i-1}f[j]*C_i^j\)

Obtained \ (F [I] \) , which is composed of the program name, the program can easily obtain a composition of several names. \ (ANS = \ sum_ {I}. 1 ^ = min {(n-, m)} F [ I] I * ^ * C_m (mi the) n-^ \) . explain this equation, \ (F [I] * C_m ^ I \) is calculated is the number of the program name, the remaining \ ((mi the) \ ) when the characters composing the name can easily fill, that is, \ ((mi) the n-^ \) .

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=2005;
const int mod=1e9+7;
ll jc[N],inv[N],f[N];
inline int ksm(int a,int b){
    int cnt=1;
    while(b){
        if(b&1)cnt=(1ll*cnt*a)%mod;
        a=(1ll*a*a)%mod;
        b>>=1;
    }
    return cnt;
}
inline int C(int n,int m){return ((1ll*jc[n]*inv[n-m])%mod*inv[m])%mod;}
int main(){
    jc[0]=1;for(int i=1;i<=2000;++i)jc[i]=(1ll*jc[i-1]*i)%mod;
    inv[2000]=ksm(jc[2000],mod-2);for(int i=2000-1;i>=0;--i)inv[i]=(1ll*inv[i+1]*(i+1))%mod;//预处理阶乘和逆元
    int T=read();
    while(T--){
        int n=read(),m=read();
        for(int i=1;i<=m;++i){
            f[i]=ksm(i,n);
            for(int j=1;j<=i-1;++j)
                f[i]=(f[i]-(1ll*f[j]*C(i,j)%mod)+mod)%mod;//这里一定要加mod,因为可能会减成负数
        }//计算f[i]
        ll ans=0;
        for(int i=1;i<=min(m,n);++i)
            ans=(ans+(1ll*f[i]*C(m,i)%mod*ksm(m-i,n))%mod)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/PPXppx/p/11428585.html