【题目链接】

https://www.lydsy.com/JudgeOnline/problem.php?id=4517

【算法】

有m个数在原来的位置上,说明有(n-m)个数不再原来的位置上

那么,我们可以选出(n-m)个数,使这(n-m)个数都不在原来的位置上,再让剩下的m个数都在原来的位置上

错位排列递推公式 :

          f(1) = 0

          f(2) = 1

          f(n) = (n - 1)(f(n-1) + f(n-2)) (n >= 2)

          因此,答案为C(n,n-m)f(n-m)

预处理错位排列数,阶乘和阶乘逆元,即可

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000010
const int P = 1e9 + ; int T,n,m,ans;
int f[MAXN],fac[MAXN],inv[MAXN]; inline int power(int a,int n)
{
int res = ,b = a;
while (n)
{
if (n & ) res = 1ll * res * b % P;
b = 1ll * b * b % P;
n >>= ;
}
return res;
}
inline void init()
{
int i;
f[] = ;
f[] = ;
f[] = ;
for (i = ; i < MAXN; i++) f[i] = 1ll * (i - ) * (f[i-] + f[i-]) % P;
fac[] = ;
for (i = ; i < MAXN; i++) fac[i] = 1ll * fac[i-] * i % P;
inv[MAXN-] = power(fac[MAXN-],P-);
for (i = MAXN - ; i >= ; i--) inv[i] = 1ll * inv[i+] * (i + ) % P;
}
inline int C(int n,int m)
{
if (n < m) return ;
if (m == ) return ;
return 1ll * fac[n] * inv[m] % P * inv[n-m] % P;
} int main()
{ init();
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
ans = 1ll * C(n,n-m) * f[n-m] % P;
printf("%d\n",ans);
} return }

最新文章

  1. 免费开源分布式系统日志收集框架 Exceptionless
  2. jenkins添加git源码目录时报Error performing command错误
  3. PL/SQL创建数据表空间
  4. C#的泛型委托Predicate/Func/Action(转)
  5. EF——Guid类型数据的自增长、时间戳和复杂类型的用法 03 (转)
  6. StringReplace用法
  7. E-BOM和M-BOM的区别
  8. Eclipse热部署JSP
  9. Ubuntu下GCC的安装以及版本控制
  10. 【grunt整合版】 30分钟学会使用grunt打包前端代码
  11. codeforces 645C . Enduring Exodus 三分
  12. gallery 从最左边开始显示并且默认选中第一个
  13. #417 Div2 C
  14. 201521123006 《Java程序设计》第1周学习总结
  15. 自己做一台3D打印机到底有多难?(附教程)
  16. get请求乱码解决
  17. 后Hadoop时代的大数据技术思考:数据即服务
  18. CSS中常见的长度单位
  19. 1.3 C++引用(Reference)
  20. BASIC-11_蓝桥杯_十六进制转十进制

热门文章

  1. jah老师中关于集合的总结
  2. Service不完全解析
  3. 6.Renderer Window
  4. 百度地图api的简单应用
  5. javascript中in运算符的介绍
  6. powershell遍历文件夹设置权限,解决文件无法删除的问题。
  7. JS 实现类似打印的效果(一个字一个字显示)
  8. PHP 时间处理
  9. BZOJ 1042: [HAOI2008]硬币购物 容斥原理_背包_好题
  10. javascript事件列表解说