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

    题目描述

    求有多少种长度为 n 的序列 A,满足以下条件:

    1 ~ n 这 n 个数在序列中各出现了一次

    若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的

    满足条件的序列可能很多,序列数对 (10^9+7) 取模。

    输入输出格式

    输入格式:

    第一行一个数 T,表示有 T 组数据。

    接下来 T 行,每行两个整数 n、m。

    输出格式:

    输出 T 行,每行一个数,表示求出的序列数

    输入输出样例

    输入样例#1:

    5
    1 0
    1 1
    5 2
    100 50
    10000 5000

    输出样例#1:

    0
    1
    20
    578028887
    60695423


    错排+组合数

    显然答案是(C(n,m) * f[n - m])

    但是当时我把错排公式忘了

    就现打表找了个好像不是很一样的递推式

    $ if (i是偶数) f[i] = f[i - 1] * i + 1$

    $ else f[i] = f[i - 1] * i - 1$

    也过掉了这道题

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    # define int long long
    const int M = 1000005 ;
    const int mod = 1e9 + 7 ;
    using namespace std ;
    inline int read() {
        char c = getchar() ; int x = 0 , w = 1 ;
        while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
        while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
        return x*w ;
    }
    int n , m , Ans ;
    int f[M] , fac[M] ;
    void exgcd(int a , int b , int &x , int &y) {
        if(b == 0) { x = 1 , y = 0 ; return ; }
        exgcd(b , a % b , x , y) ;
        int tmp = x ;
        x = y ;
        y = tmp - a / b * y ;
    }
    inline int inv(int a) {
        int x , y ;
        exgcd(a , mod , x , y) ;
        return (x + mod) % mod ;
    }
    inline int C(int n , int m) {
        if(m > n) return 0 ;
        return (fac[n] * inv(fac[m] * fac[n - m]) + mod) % mod ;
    }
    # undef int
    int main() {
    # define int long long
        f[0] = 1 ; f[1] = 0 ; fac[0] = 1 ; fac[1] = 1 ;
        for(int i = 2 ; i <= 1000000 ; i ++) {
            if(i % 2 == 0) f[i] = (f[i - 1] * i + 1 + mod) % mod ;
            else f[i] = (f[i - 1] * i - 1 + mod) % mod ;  
            fac[i] = (fac[i - 1] * i) % mod ;
        }
        int T = read() ;
        while(T --) {
            n = read() ; m = read() ;
            if(m > n) Ans = 0 ;
            else Ans = (C(n , m) * f[n - m] + mod) % mod ;
            printf("%lld
    ",Ans) ;
        }
        return 0 ;
    }
    
    
  • 相关阅读:
    nyoj118 修路工程 次小生成树
    nyoj99 单词连接 欧拉回路
    NYOJ289 苹果 典型背包
    nyoj 139 牌数 康拓展开
    poj1423 NYOJ_69 数字长度 斯特林公式 对数应用
    NYOJ311 完全背包 对照苹果
    sort 函数的应用
    NYOJ120 校园网络 强连接
    nyoj219 计算日期 吉姆拉森公式
    把SmartQ5系统装在SD卡上
  • 原文地址:https://www.cnblogs.com/beretty/p/9765481.html
Copyright © 2011-2022 走看看