【BZOJ】4517 [Sdoi2016]排列计数
2016-09-01 16:52
267 查看
Description
求有多少种长度为 n 的序列 A,满足以下条件:
1 ~ n 这 n 个数在序列中各出现了一次
若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的
满足条件的序列可能很多,序列数对 109+7 取模。
Input
第一行一个数 T,表示有 T 组数据。
接下来 T 行,每行两个整数 n、m。
T=500000,n≤1000000,m≤1000000
Output
输出 T 行,每行一个数,表示求出的序列数
Solution
n个数中选出m个数作为“稳定的数”,剩下的数错排
错排问题的公式(递推式)
f[n]=n∗f[n−1]+(−1)n
f[0]=1
因为模数是质数,所以组合数分母的逆元可以暴力算
求有多少种长度为 n 的序列 A,满足以下条件:
1 ~ n 这 n 个数在序列中各出现了一次
若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的
满足条件的序列可能很多,序列数对 109+7 取模。
Input
第一行一个数 T,表示有 T 组数据。
接下来 T 行,每行两个整数 n、m。
T=500000,n≤1000000,m≤1000000
Output
输出 T 行,每行一个数,表示求出的序列数
Solution
n个数中选出m个数作为“稳定的数”,剩下的数错排
错排问题的公式(递推式)
f[n]=n∗f[n−1]+(−1)n
f[0]=1
因为模数是质数,所以组合数分母的逆元可以暴力算
#include<cstdio> #define mod 1000000007 #define N 1000005 int T,t ,f ,n,m; inline int time(int a,int b) { int ans=1; while (b) { if (b&1) ans=1LL*ans*a % mod; a=1LL*a*a % mod,b>>=1; } return ans; } int main() { scanf("%d",&T);t[0]=f[0]=1; for (int i=1;i<1000001;i++) t[i]=1LL*t[i-1]*i % mod,f[i]=(1LL*f[i-1]*i+((i&1)?-1:1)) % mod; while (T--) { scanf("%d%d",&n,&m); printf("%d\n",(1LL*f[n-m]*t % mod)*time(1LL*t[m]*t[n-m] % mod,mod-2) % mod); } }
相关文章推荐
- bzoj 4517: [Sdoi2016]排列计数(错排+组合数逆元)
- bzoj 4517: [Sdoi2016]排列计数
- BZOJ 4517 [Sdoi2016]排列计数
- BZOJ 4517: [Sdoi2016]排列计数 组合数 错排公式
- BZOJ 4517: [Sdoi2016]排列计数
- bzoj 4517: [Sdoi2016]排列计数【容斥原理+组合数学】
- BZOJ_4517_[Sdoi2016]排列计数_组合数学
- BZOJ 4517 [Sdoi2016]排列计数
- BZOJ 4517|SDOI 2016|排列计数|错排公式|组合数学
- bzoj-4517 4517: [Sdoi2016]排列计数(组合数学)
- BZOJ 4517 [Sdoi2016]排列计数
- bzoj 4517: [Sdoi2016]排列计数 排列组合+动态规划
- bzoj 4517: [Sdoi2016]排列计数
- bzoj 4517: [Sdoi2016]排列计数
- bzoj 4517: [Sdoi2016]排列计数 递推
- BZOJ 4517: [Sdoi2016]排列计数 错排公式
- [组合 错排] BZOJ 4517 [Sdoi2016]排列计数
- BZOJ 4517: [Sdoi2016]排列计数 错排+逆元
- Bzoj 4517: [Sdoi2016]排列计数(排列组合)
- bzoj 4517 [Sdoi2016]排列计数