zoukankan      html  css  js  c++  java
  • 4517: [Sdoi2016]排列计数

    链接

    思路:

      首先,要确定定m个位置,这些位置要求必须i=a[i],所以方案数是C(n,m),对于剩下的位置,要求i!=a[i],所以要求是一个错排。

    错排公式

    p[0] = 0,p[1] = 1

    p[i] = (i-1)*(p[i-1]+p[i-2])

    代码

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 
     7 using namespace std;
     8 
     9 const int mod = 1e9+7;
    10 
    11 int f[1000100],p[1000100];
    12 
    13 inline int read() {
    14     int x = 0,f = 1;char ch=getchar();
    15     for (; ch<'0'||ch>'9'; ch=getchar()) if(ch=='-')f=-1;
    16     for (; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
    17     return x*f;
    18 }
    19 
    20 void init() {
    21     f[0] = 1;
    22     for (int i=1; i<=1000000; ++i) f[i] = (1ll * f[i-1] * i) % mod;
    23     p[1] = 0;p[2] = 1;
    24     for (int i=3; i<=1000000; ++i) p[i] = (1ll * (i-1) * (p[i-1] + p[i-2])) % mod;
    25 }
    26 
    27 int inv(int a,int b) {
    28     int ans = 1;
    29     while (b) {
    30         if (b & 1) ans = (1ll*ans*a) % mod;
    31         a = (1ll * a * a) % mod;
    32         b >>= 1;
    33     }
    34     return ans % mod;
    35 }
    36 
    37 void solve(int n,int m) {
    38     if (n == m) {cout << "1
    ";return ;}
    39     int t1 = inv(f[m],mod-2),t2 = inv(f[n-m],mod-2);
    40     int ans = (1ll * f[n] * t1) % mod;
    41     ans = (1ll * ans * t2) % mod;
    42     ans = (1ll * ans * p[n-m]) % mod;
    43     cout << ans << "
    ";
    44 }
    45 
    46 int main() {
    47     int T = read();
    48     init();
    49     while (T--) {
    50         int n = read(),m = read();
    51         solve(n,m);
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    226_翻转二叉树
    199_二叉树的右视图
    145_二叉树的后序遍历
    做IT,网络/系统/数据库/软件开发都得懂
    [恢]hdu 1200
    [恢]hdu 2080
    [恢]hdu 1222
    [恢]hdu 1128
    [恢]hdu 2153
    [恢]hdu 2132
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8709801.html
Copyright © 2011-2022 走看看