这道题是数学题,由题目可知,m个稳定数的取法是Cnm

然后剩下n-m本书,由于编号为i的书不能放在i位置,因此其方法数应由错排公式决定,即D(n-m)

  错排公式:D[i]=(i-1)*(D[i-1]+D[i-2]);

所以根据乘法原理,答案就是Cnm * D(n-m)

接下来就是怎么求组合数的问题了

由于n≤1000000,因此只能用O(n)的算法求组合,这里用乘法逆元(inv[])来辅助求组合数

即 Cnm = n! / ((n-m)! * m!) = fac[n]*inv[n-m]*inv[m]

那么乘法逆元是什么呢?

假设一个数a,且a关于P的乘法逆元为x

那么 ax≡1 (mod P). 当且仅当 a 与 P 互质时x有解

简单的说,就是找一个数x,使得(x*a) mod P = 1

不难得出三者符合 ax+Py=1 (裴蜀定理), y可能是负数

因此我们可以用拓展欧几里得算出x的值,即为乘法逆元(用inv保存)

对于求出inv的过程,我们可以不必每次暴力求拓展欧几里得,可由下列递推式O(n)求出

  inv[i]=(i+1)*inv[i+1]

而D数组只要O(n)推即可,其中D[0]=1, D[1]=0;

这道题让我明白。。组合数可以O(n)求得,了解了乘法逆元是什么,并且了解到世界上有个叫错排公式的神奇东西Orz

 #include<stdio.h>
 #include<algorithm>
 #include<string.h>
 #define LL long long
 using namespace std;
 ;
 ;
 int T,n,m;
 LL f[maxn],inv[maxn],d[maxn];

 inline void read(int &x){
     ;
     ') c=getchar();
     +c-, c=getchar();
 }

 inline LL ex_gcd(LL &x, LL &y, LL a, LL b){
     ){
         x=; y=;
         return a;
     }
     LL res=ex_gcd(x,y,b,a%b);
     LL t=x; x=y;
     y=t-a/b*x;
     return res;
 }

 inline LL calc(LL a, LL b){
     LL x,y;
     if (ex_gcd(x,y,a,b) == 1LL)
         return (x+b)%b;
 }

 int main(){
     read(T);
     f[]=;
     ; i<=maxn; i++) f[i]=f[i-] * (LL)i % MOD;
     inv[]=calc(f[],MOD);
     ; i>=; i--) inv[i]=inv[i+] * (LL)(i+) % MOD;
     d[]=; d[]=; d[]=;
     ; i<=maxn; i++) d[i]=(LL)(i-)*(d[i-]+d[i-]) % MOD;
     while (T--){
         read(n); read(m);
         LL ans=1LL;
         //printf("haha %lld %lld %lld %lld\n", f[n], inv[n-m], inv[m], d[n-m]);
         ans=ans*f[n]*inv[n-m] % MOD;
         ans=ans*inv[m] % MOD;
         ans=ans*d[n-m] % MOD;
         printf("%lld\n", ans);
     }
     ;
 }

bzoj4517: [Sdoi2016]排列计数--数学+拓展欧几里得的更多相关文章

  1. [BZOJ4517] [Sdoi2016] 排列计数 (数学)

    Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是 ...

  2. BZOJ4517 Sdoi2016 排列计数 【DP+组合计数】*

    BZOJ4517 Sdoi2016 排列计数 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 ...

  3. [BZOJ4517][SDOI2016]排列计数(错位排列)

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1616  Solved: 985[Submit][Statu ...

  4. bzoj4517[Sdoi2016]排列计数(组合数,错排)

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1792  Solved: 1111[Submit][Stat ...

  5. 2018.10.25 bzoj4517: [Sdoi2016]排列计数(组合数学)

    传送门 组合数学简单题. Ans=(nm)∗1Ans=\binom {n} {m}*1Ans=(mn​)∗1~(n−m)(n-m)(n−m)的错排数. 前面的直接线性筛逆元求. 后面的错排数递推式本蒟 ...

  6. BZOJ4517——[Sdoi2016]排列计数

    求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是稳定的 满足条件的序列可 ...

  7. BZOJ4517: [Sdoi2016]排列计数

    Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是 ...

  8. bzoj千题计划282:bzoj4517: [Sdoi2016]排列计数

    http://www.lydsy.com/JudgeOnline/problem.php?id=4517 组合数+错排公式 #include<cstdio> #include<ios ...

  9. BZOJ4517:[SDOI2016]排列计数(组合数学,错排公式)

    Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是 ...

随机推荐

  1. CentOS配置本地yum源(使用镜像iso文件)

    本人在使用yum安装软件的时候,感觉最不爽的是网络不佳时,安装的速度特别慢.所以,个人就上网search了一下如何使用Linux的安装文件作为其yum源.经过几次尝试,已经可以成功的配置了.下面是详细 ...

  2. Liferay 6.2 改造系列之二十二:如何发布WAR包

    1.修改web资源并发布 如果修改了默认主题信息,需执行portal-web中的build-themes任务: 执行portal-web中的deploy任务: 2.修改portal-impl中的jav ...

  3. 20145223《Java程序程序设计》第1周学习总结

    20145223 <Java程序设计>第1周学习总结 教材学习内容总结 1.JDK.JRE以及JVM的区别 JDK:撰写java程序语言的时候需要用到的编译工具 JRE:java执行环境 ...

  4. jQuery-事件以及动画

    事件: 1.//方法1 $(window).load(function(){ }) window.onload=function(){ } //方法2 function one(){ alert(&q ...

  5. json解析不推荐使用eval

    推荐使用JSON.parse() 低版本浏览器(IE6/7)不支持此方法,可以通过网上下载json2.js,引入到文件中,此文件通过判断浏览器是否支持JSON.parse()方法,如果不支持,文件中编 ...

  6. Regionals 2012 :: Chengdu

    题目连接 排行榜 A和I都是签到题 按位BFS K Yet Another Multiple Problem 题意:给一些可以用的数字,求最小的数,它由特定的数字组成且是n的倍数 分析:暴力枚举不可行 ...

  7. Codeforces 627A XOR Equation(思路)

    题目大概说两个正整数a.b,已知s=a+b以及x=a xor b的值,问有几种a.b这样的数对. 我知道异或相当于无进位的加法,s-x就是其各个位置的进位,比如s-x=1010,那就表示a和b的第1位 ...

  8. hive0.12 rcfile gzip 测试

    创建test_rc; 让后从老数据中插入test_rc中, select test_rc 中插入的数据,报如下错误: Failed with exception java.io.IOException ...

  9. HDU 1072(记忆化BFS)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1072 题目大意:走迷宫.走到装置点重置时间,到达任一点时的时间不能为0,可以走重复路,求出迷宫最短时 ...

  10. Oracle 时间,日期 类型函数及参数详解

    ORACLE字符数字日期之间转化   Java代码   24 小时的形式显示出来要用 HH24       select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss' ...