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 ;
    }
    
    
  • 相关阅读:
    LeetCode 461. Hamming Distance
    LeetCode 442. Find All Duplicates in an Array
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode Find the Difference
    LeetCode 415. Add Strings
    LeetCode 445. Add Two Numbers II
    LeetCode 438. Find All Anagrams in a String
    LeetCode 463. Island Perimeter
    LeetCode 362. Design Hit Counter
    LeetCode 359. Logger Rate Limiter
  • 原文地址:https://www.cnblogs.com/beretty/p/9765481.html
Copyright © 2011-2022 走看看