这道题是数学题,由题目可知,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. loopback 05

    数据并发处理 数据库事务 事务隔离 ACID性质 原子性(Atomicity): 要么全部被执行,要么都不执行; 一致性(Consistency): 满足完整性约束; 隔离性(Isolation): ...

  2. JS(获得当前时间并且用2015-01-01格式表示)

    一个简单的小例子,实现获得当前时间,js代码如下: function getdate() {var date = new Date();var mon = date.getMonth()  + 1;  ...

  3. 【Highcharts】 动态删除series

    先绘制,后删除多余 var chart = new Highcharts.Chart(options); if (chart.series.length > result.dataList0.l ...

  4. three.js加入监控

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. three.js右手坐标系, 显示和线条

    1.右手坐标系 Threejs使用的是右手坐标系,这源于opengl默认情况下,也是右手坐标系.下面是右手坐标系的图例,如果对这个概念不理解,可以百度一下,我保证你伸出手比划的那一瞬间你就明白了,如果 ...

  6. EF框架step by step(4)—DBcontext应用于已存在数据库

    EF4.1有三种方式来进行数据操作及持久化.分别是Database-First,Model-First,Code-first,前面都已经简单介绍过了.下面简单小结一下:1.Database First ...

  7. Money类型转化为String去除小数点后0解决方法

    Money类型转化为String去除小数点后0从数据库提取Money类型后,字符串如:1212.0000 如何使其成为1212             注:去掉了小数点 如果是:1212.0100 使 ...

  8. 【oracle】解锁oracle用户,unlock

    解除oracle用户的锁定状态,例如oracle数据库建立测试实例时默认建立的scott用户,一开始是处于locked状态的,现在我们需要将其解锁,步骤如下: (1)在cmd中登录sqlplus,例如 ...

  9. python 代码片段23

    #coding=utf-8 #python还支持动态的实力属性,即那些没有在类定义里生命的属性, #可以"凭空"创造出来 john.tatto='Mom' #继承 class Em ...

  10. topcoder SRM 610 DIV2 TheMatrix

    题目的意思是给一个01的字符串数组,让你去求解满足棋盘条件的最大棋盘 棋盘的条件是: 相邻元素的值不能相同 此题有点像求全1的最大子矩阵,当时求全1的最大子矩阵是用直方图求解的 本题可以利用直方图求解 ...