zoukankan      html  css  js  c++  java
  • [SDOI2016]排列计数

    [SDOI2016]排列计数

    有一个长度为n的1~n的全排列,如果一个数i出现在第i个位置上,则称该数是稳定的,询问恰好有m个数是稳定的全排列的方案数,(n≤1000000,m≤1000000)

    显然为组合计数题,于是我们来相办法划分问题,如果事先选出m个数让其稳定,不难得知剩下的问题就是一个错排问题,而对于错排问题,设(f_i)表示长度为i的错排方案数,我们又有递推公式(f_i=(i-1) imes(f_{i-1}+f_{i-2})),边界(f_2=1),把两者相乘即答案。

    参考代码:

    #include <iostream>
    #include <cstdio>
    #define il inline
    #define ri register
    #define yyb 1000000007
    #define ll long long
    using namespace std;
    ll f[1000001],jc[1000001],jv[1000001];
    il ll pow(ll,ll),c(int,int);
    il void read(int&),prepare(int);
    int main(){
        int lsy;read(lsy),prepare(1000000);
        while(lsy--){
            int n,m;
            read(n),read(m);
            printf("%lld
    ",c(n,m)*f[n-m]%yyb);
        }
        return 0;
    }
    il ll c(int n,int r){
        if(n<r)return 0;
        return jc[n]*jv[r]%yyb*jv[n-r]%yyb;
    }
    il ll pow(ll x,ll y){
        ll ans(1);while(y){
            if(y&1)(ans*=x)%=yyb;
            (x*=x)%=yyb,y>>=1;
        }return ans;
    }
    il void prepare(int n){
        f[0]=jv[0]=f[2]=jc[0]=1;
        for(int i(3);i<=n;++i)
            f[i]=(i-1)*(f[i-1]+f[i-2])%yyb;
        for(int i(1);i<=n;++i)jc[i]=jc[i-1]*i%yyb;
        jv[n]=pow(jc[n],yyb-2);
        for(int i(n);i>1;--i)jv[i-1]=jv[i]*i%yyb;
    }
    il void read(int &x){
        x&=0;ri char c;while(c=getchar(),c<'0'||c>'9');
        while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    }
    
    
  • 相关阅读:
    代理模式和装饰模式的理解
    Mysql常用命令
    java动态代理(JDK和cglib)
    MyEclipse中SVN使用步骤
    ActionContext和ServletActionContext小结
    java和unicode
    Win7下telnet使用
    MyEclipse8.5安装SVN插件
    linux常用命令(基础)
    选择TreeView控件的树状数据节点的JS方法
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/10932315.html
Copyright © 2011-2022 走看看