题目

求有多少种长度为 n 的序列 A,满足以下条件:

1 ~ n 这 n 个数在序列中各出现了一次

若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的

满足条件的序列可能很多,序列数对 10^9+7 取模。

输入格式

第一行一个数 T,表示有 T 组数据。

接下来 T 行,每行两个整数 n、m。

T=500000,n≤1000000,m≤1000000

输出格式

输出 T 行,每行一个数,表示求出的序列数

输入样例

5

1 0

1 1

5 2

100 50

10000 5000

输出样例

0

1

20

578028887

60695423

题解

考虑哪些位置是稳定的,剩余位置就不能稳定

我们设\(f[i]\)表示\(i\)个数都不稳定的方案数

那么\(ans = C_{n}^{m} * f[n - m]\)

我们预处理阶乘和\(f[i]\)就可以了

对于\(f[i]\),我们考虑第\(i\)个数放哪,显然有\(i - 1\)个位置可以放

放完后剩余\(i - 1\)个数和\(i - 1\)个位置,其中有一个位置都可以放,有一个数的位置被占了,所以可以任意放

那我们设\(g[i]\)表示这种情况下的方案数,如果我们称那个可以任意放的数为自由元,那个位置为自由位置

那么我们考虑自由元放在什么位置

①如果放在自由位置,那么剩余的数成了\(f[i - 1]\)

②如果不放在自由位置,有\(i - 1\)个位置,剩余\(i - 1\)的方案就是\(g[i - 1]\)

综上

\[f[i] = (i - 1) * g[i - 1]
\]

\[g[i] = f[i - 1] + (i - 1) * g[i - 1]
\]

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 1000005,maxm = 100005,INF = 1000000000,P = 1000000007;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
LL fac[maxn],inv[maxn],fv[maxn],f[maxn],g[maxn];
int n,m,T;
LL C(int x,int y){
return fac[x] * fv[y] % P * fv[x - y] % P;
}
int main(){
fac[0] = 1;
for (int i = 1; i <= 1000000; i++) fac[i] = fac[i - 1] * i % P;
inv[0] = inv[1] = 1;
for (int i = 2; i <= 1000000; i++) inv[i] = (P - P / i) * inv[P % i] % P;
fv[0] = 1;
for (int i = 1; i <= 1000000; i++) fv[i] = fv[i - 1] * inv[i] % P;
f[0] = 1; f[1] = 0; g[1] = 1; g[0] = 1;
for (int i = 2; i <= 1000000; i++){
f[i] = (i - 1) * g[i - 1] % P;
g[i] = (f[i - 1] + (i - 1) * g[i - 1] % P) % P;
}
T = read();
while (T--){
n = read(); m = read();
printf("%lld\n",C(n,m) * f[n - m] % P);
}
return 0;
}

BZOJ4517 [Sdoi2016]排列计数 【组合数 + dp】的更多相关文章

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

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

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

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

  3. 【bzoj4517】[Sdoi2016]排列计数 组合数+dp

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

  4. BZOJ4517: [Sdoi2016]排列计数(组合数+错位排列)

    Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1626  Solved: 994[Submit][Status][Discuss] Descripti ...

  5. 【BZOJ4517】[Sdoi2016]排列计数 组合数+错排

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

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

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

  7. 洛谷P2606 [ZJOI2010]排列计数(组合数 dp)

    题意 题目链接 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案 ...

  8. bzoj4517: [Sdoi2016]排列计数--数学+拓展欧几里得

    这道题是数学题,由题目可知,m个稳定数的取法是Cnm 然后剩下n-m本书,由于编号为i的书不能放在i位置,因此其方法数应由错排公式决定,即D(n-m) 错排公式:D[i]=(i-1)*(D[i-1]+ ...

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

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

随机推荐

  1. 八数码问题(一) 暴力BFS + STL

    八数码问题是一个经典的人工智能问题.具体问题不累述了. 思路:由于存在多组测试数据,可以考虑“打表法“.所谓打表法,即枚举所有的初始情况,记录其到达终点的路径.而在这个题目中,顺序打表会调用很多次BF ...

  2. Array - Container With Most Water

    /** * 此为暴力解法 * Find two lines, which together with x-axis forms a container, such that the container ...

  3. 使用Process组件访问本地进程

    实现效果; 知识运用: Process组件的StartInfo属性 //获取或设置要传递给Process的Start方法的属性 public ProcessStartInfo StartInfo {g ...

  4. 查看numpy的类型

    查看一个变量的类型:type(img) 查看array中的数据值的类型:img.dtype 查看array的形状:img.shape

  5. java利用SuffixFileFilter统计目录下特定后缀名文件的数目

    /** * 文件处理类 * @author zhangcd * @date 2017年1月3日 */ public class FileUtil { /** * 得到所有后缀的数目 * * @para ...

  6. JSON.stringify(value[, replacer[, space]])

    1. JSON.stringify(value[, replacer[, space]]);value 必需 对象或数组,需要转换成json字符串的数据replacer 可选 函数或数组space 可 ...

  7. C++中有三种创建对象的方法

    #include <iostream> using namespace std; class A { private: int n; public: A(int m):n(m) { } ~ ...

  8. 配置httpd虚拟主机

    轻松配置httpd的虚拟主机 httpd使用VirtualHost指令进行虚拟主机的定义.支持三种虚拟主机:基于ip,基于端口和基于名称.其中基于端口的虚拟主机在httpd的术语上(例如官方手册)也属 ...

  9. 【android】6大布局

    线性布局 相对布局 绝对布局 网格布局 表格布局 帧布局

  10. linux中怎样关闭ICMP回应功能

    引用自:http://blog.csdn.net/qq844352155/article/details/49700121 linux中怎样关闭ICMP回应功能   输入:   echo 1 > ...