P4071 [SDOI2016]排列计数
题目描述
求有多少种长度为 n 的序列 A,满足以下条件:
1 ~ n 这 n 个数在序列中各出现了一次
若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的
满足条件的序列可能很多,序列数对 109+7 取模。
输入输出格式
输入格式:
第一行一个数 T,表示有 T 组数据。
接下来 T 行,每行两个整数 n、m。
输出格式:
输出 T 行,每行一个数,表示求出的序列数
输入输出样例
5
1 0
1 1
5 2
100 50
10000 5000
0
1
20
578028887
60695423
说明
测试点 1 ~ 3: T=1000,n≤8,m≤8;
测试点 4 ~ 6: T=1000,n≤12,m≤12;
测试点 7 ~ 9: T=1000,n≤100,m≤100;
测试点 10 ~ 12:T=1000,n≤1000,m≤1000;
测试点 13 ~ 14:T=500000,n≤1000,m≤1000;
测试点 15 ~ 20:T=500000,n≤1000000,m≤1000000。
Solution:
本题组合数学+错排公式+线推逆元。
组合数学和逆元就不说了,介绍下错位排列。
错位排列,顾名思义就是一个n元排列,每个元素不能排在自己的位置上的方案数,一般记作$D(n)$。
通项公式:
$$D_n=n!\times(1-\frac{1}{1!}+\frac{1}{2!}-\frac{1}{3!}…\frac{(-1)^n}{n!})$$
证明:
设$S$是由$1,2,…n$构成的所有全排列组成的集合,则$|S|=n!$。
设$A_i$是在$1,2,…n$的所有排列种由第$i$个位置上的元素恰好是$i$的所有排列组成的集合,则有:$|A_i|=(n-1)!$。
同理可得:$|A_i\cap A_j|=(n-2)!$
……
一般情况下有:$|A_{i1}\cap A_{i2}\cap …\cap A_{ik}|=(n-k)!$。
因为$D_n$是$S$中不满足性质$P_1,P_2,…,P_n$的元素个数,所以由容斥原理的:
$D_n=|\overline A_1\cap \overline A_2 …\cap \overline A_n|$
$=n!-C(n,1)*(n-1)!+C(n,2)*(n-2)!-…(-1)^nC(n,n)*0!$
$=n!\times(1-\frac{1}{1!}+\frac{1}{2!}-…\frac{(-1)^n}{n!})$
递推公式:
$$D_n=(n-1)\times(D_{n-1}+D_{n-2})$$
证明:
第一步,把第$n$个元素放在一个位置,比如位置$k$,一共有$n-1$种方法;
第二步,放编号为$k$的元素,这时有两种情况:(1)把它固定到位置$n$,由于第$n$个元素固定到了位置$k$,剩下$n-2$个元素就有$D_{n-2}$种方法;(2)第$k$个元素不能放到位置$n$,而第$n$个元素固定到了位置$k$,于是$n-1$个元素,有$D_{n-1}$种方法;
综上得到$D_n = (n-1) \times(D_{n-2} + D_{n-1})$,特殊地,$D_1=0, D_2=1$。
当然更为常用的是后面的递推公式,比如本题。
不难发现本题答案为$C(n,m)\times D(n-m)$。
于是我们只要预处理出$10^6$内的阶乘取模、阶乘的逆元、错排的方案数就好了。
代码:
/*Code by 520 -- 9.14*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const ll N=,mod=1e9+;
int n,m;
ll d[N],c[N],inv[N]; int gi(){
int a=;char x=getchar();
while(x<''||x>'')x=getchar();
while(x>=''&&x<='')a=(a<<)+(a<<)+(x^),x=getchar();
return a;
} il void Pre(){
d[]=,d[]=;
For(i,,) d[i]=(i-)*(d[i-]+d[i-])%mod;
c[]=,c[]=,inv[]=;
For(i,,) c[i]=c[i-]*i%mod,inv[i]=(mod-mod/i*inv[mod%i]%mod)%mod;
For(i,,) inv[i]=inv[i]*inv[i-]%mod;
} int main(){
Pre();
int T=gi();
while(T--) {
n=gi(),m=gi();
if(n-m==) printf("0\n");
else if(n==m) printf("1\n");
else if(!m) printf("%lld\n",d[n]);
else printf("%lld\n",c[n]*inv[m]%mod*inv[n-m]%mod*d[n-m]%mod);
}
return ;
}
P4071 [SDOI2016]排列计数的更多相关文章
- 洛谷——P4071 [SDOI2016]排列计数(错排+组合数学)
P4071 [SDOI2016]排列计数 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列 ...
- 洛谷 P4071 [SDOI2016]排列计数 题解
P4071 [SDOI2016]排列计数 题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳 ...
- 洛谷P4071 [SDOI2016] 排列计数 [组合数学]
题目传送门 排列计数 题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m ...
- Luogu P4071 [SDOI2016]排列计数
晚上XZTdalao给我推荐了这道数论题.太棒了又可以A一道省选题了 其实这道题也就考一个错排公式+组合数+乘法逆元 我们来一步一步分析 错排公式 通俗的说就是把n个1~n的数排成一个序列A,并使得所 ...
- 洛谷 P4071 [SDOI2016]排列计数
洛谷 这是一道组合数学题. 对于一个长为n的序列,首先我们要选m个使之稳定\(C^{m}_{n}\). 且要保证剩下的序列不稳定,即错排\(D_{n-m}\). 所以答案就是:\[ANS=C^{m}_ ...
- P4071 [SDOI2016]排列计数 题解
分析: 线性求逆元:https://blog.csdn.net/qq_34564984/article/details/52292502 代码: #include<cstdio> usin ...
- 数学【洛谷P4071】 [SDOI2016]排列计数
P4071 [SDOI2016]排列计数 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列 ...
- BZOJ 4517: [Sdoi2016]排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 911 Solved: 566[Submit][Status ...
- bzoj-4517 4517: [Sdoi2016]排列计数(组合数学)
题目链接: 4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 846 Solved: 530[Submit][ ...
随机推荐
- 用CSS3做3D动画的那些事
年会做了个3D变换的抽奖系统,在这里分享下通过CSS3制作3D效果的心得.抽奖系统虽然够炫酷,可惜抽的时候出了点bug,好几百人啊我的小心脏啊.虽然这个锅后面甩给会场的老爷电脑了(手动白眼). 首先介 ...
- PS入门到精通完全自学教程
ps视频教程,ps自学视频教程.ps免费视频教程下载,PS入门到精通完全自学教程视频内容较大,分为俩部分: PS入门到精通完全自学教程-第一部分(带swf播放器):百度网盘,https://pan.b ...
- HTML中的map和area标签
1. 标签介绍: (1)map标签: 该标签是指图片的映射,也就是说一张可以点击的图片的映射: 属性介绍: <1> id: <img>中的 usemap 属性可引用 <m ...
- Python 循环的技巧
当在字典中循环时,用 items() 方法可将关键字和对应的值同时取出 >>> knights = {'gallahad': 'the pure', 'robin': 'the br ...
- 03_set slice的时间复杂度
set slice O(n+k) 使用切片赋值来解释set slice的时间复杂度 (1) 对li[0:3]赋值首先会删除1,2,3,空出来的位置被后面的元素依次向前移动填充,由del slice 得 ...
- kali vmtools 不能复制粘贴解决方法(绝对实用)
朋友问起怎么vm kali 2019怎么不能复制了,而且网上的方法大多不适合.我就在这儿记录一笔吧,方便大家. 之前发现最新kali复制粘贴不能用,后来发现一个奇妙的套路,不是共享文件夹.只需要把文件 ...
- Linux shell中&,&&,|,||的用法
前言 在玩dvwa的命令注入漏洞的时候,遇到了没有预料到的错误,执行 ping 127.0.0.1 & echo "<?php phpinfo(); ?>" & ...
- 第十次ScrumMeeting博客
第十次ScrumMeeting博客 本次会议于11月5日(日)22时整在新主楼G座2楼召开,持续20分钟. 与会人员:刘畅.辛德泰.窦鑫泽.张安澜.赵奕.方科栋. 特邀嘉宾:陈彦吉学长. 1. 每个人 ...
- 20135316王剑桥 linux第六周课实验笔记
6.存储器层次结构 6.1存储技术 1.如果你的程序需要的数据是存储在CPU寄存器中的,那么在执行期间,在零个周期内就能访问到它们.如果存储在高速缓冲中,需要1-10个周期.如果存储在主存中,需要50 ...
- php与nginx之间的通信
Nginx是俄国人最早开发的Webserver,现在已经风靡全球,相信大家并不陌生.PHP也通过二十多年的发展来到了7系列版本,更加关注性能.这对搭档在最近这些年,叱咤风云,基本上LNMP成了当下的标 ...