bzoj 4517: [Sdoi2016]排列计数 排列组合+动态规划
2017-03-11 15:59
337 查看
题意
求有多少种长度为 n 的序列 A,满足以下条件:1 ~ n 这 n 个数在序列中各出现了一次
若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的
满足条件的序列可能很多,序列数对 10^9+7 取模。
T=500000,n≤1000000,m≤1000000
分析
设f[i]表示i的排列的错排方案,显然f[i]=f[i−1]∗(i−1)+f[i−2]∗(i−1)那么ans=Cmn∗f[n−m]
预处理阶乘逆元和f数组即可。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define N 1000005 #define MOD 1000000007 #define LL long long using namespace std; int f ,jc ,ny ; int ksm(int x,int y) { int ans=1; while (y) { if (y&1) ans=(LL)ans*x%MOD; x=(LL)x*x%MOD;y>>=1; } return ans; } void prework() { jc[0]=ny[0]=1; for (int i=1;i<=1000000;i++) { jc[i]=(LL)jc[i-1]*i%MOD; ny[i]=ksm(jc[i],MOD-2); } f[1]=0;f[2]=1; for (int i=3;i<=1000000;i++) f[i]=((LL)f[i-1]*(i-1)%MOD+(LL)f[i-2]*(i-1)%MOD)%MOD; f[0]=1; } int main() { int T; scanf("%d",&T); prework(); while (T--) { int n,m; scanf("%d%d",&n,&m); printf("%d\n",(LL)jc *ny[m]%MOD*ny[n-m]%MOD*f[n-m]%MOD); } return 0; }
相关文章推荐
- [组合 错排] BZOJ 4517 [Sdoi2016]排列计数
- BZOJ 4517: [Sdoi2016]排列计数 组合数 错排公式
- bzoj-4517 4517: [Sdoi2016]排列计数(组合数学)
- BZOJ 4517|SDOI 2016|排列计数|错排公式|组合数学
- 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]排列计数 错排+逆元
- BZOJ 4517 [Sdoi2016]排列计数
- bzoj 4517: [Sdoi2016]排列计数【容斥原理+组合数学】
- BZOJ 4517: [Sdoi2016]排列计数 错排公式
- bzoj 4517: [Sdoi2016]排列计数
- 【BZOJ 4517】【SDOI 2016 Round1 Day2 T2】排列计数
- BZOJ 4517: [Sdoi2016]排列计数 [容斥原理]