JZOJ4474 [] []に配置されているカウンタluoguP4071

説明

:長さN Aの何配列を求めて、以下の条件が満たされた
1〜数のそれぞれにNの順序で一度表示され、N(1)。
(2)i番目のA [i]がIである場合、私は安定であると述べました。M系列の数で正確に安定化
配列は、条件は、10 ^ 7 + 9 MODのシーケンスの数に多くてもよい満たします。


分析

  • 最初の\(N- \)番目、ある\(m個\)安定であるが不明ため番目、それは(C ^ {M} _ \ {N} \) プログラムの種類

  • 残り\(NM \)数は、その位置の値に配置するようにしてはならない\(NM \)プログラム番号千鳥の数

  • セット(\ [I] F)\表す\(Iは\)番号を挿入するために、今再びプログラム番号千鳥の数を\(N-を\)の前に\(N-1 \)の数が千鳥を有します

  • \(N \)確実に置くことができない\(N \)ビットだけ他置くことができる\(N-1 \)ビット

  • もし\(\ N-)のセクションに\(K \)ビットと\(K \)\(\ N-)ビット、残りの\(N-2 \)依然としてスタッガードの数

  • 場合\(N- \)のセクションに\(K \)ビットと\(K \)がされていない配置\(N- \)ビットを、次いで添加中\(N- \)\(N-1 \) 1行のも間違った番号

  • ための\(K \)している\(N-1 \)を可能とし、\(F [I] =( I-1)*(\ [I-2])F [I-1] + F)

  • したがって、彼らは問題を解決するため、答えは\(C ^ {M} _ {N} * F [nm]の\)


コード

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAX 1000000
#define mod 1000000007
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)

using namespace std;

ll f[MAX+5],fac[MAX+5],inv[MAX+5];
ll n,m,T;

inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
    while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
inline ll pow(ll x,ll y)
{
    ll z=1;
    while (y)
    {
        if (y%2)z=z*x%mod;
        x=x*x,y>>=1;
    }
    return z;
}
inline ll C(ll m,ll n)
{
    return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
    freopen("permutation.in","r",stdin);
    freopen("permutation.out","w",stdout);
    f[0]=1,f[1]=0,f[2]=1,fac[0]=1,inv[0]=inv[1]=1;
    fo(i,1,MAX)fac[i]=fac[i-1]*i%mod;
    fo(i,2,MAX)inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    fo(i,2,MAX)inv[i]=inv[i-1]*inv[i]%mod;
    fo(i,3,MAX)f[i]=(i-1)*(f[i-1]+f[i-2])%mod;
    T=read();
    while (T--)
    {
        n=read(),m=read();
        printf("%lld\n",C(m,n)*f[n-m]%mod);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/horizonwd/p/11295294.html