博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 4517: [Sdoi2016]排列计数(组合数学)
阅读量:4988 次
发布时间:2019-06-12

本文共 1524 字,大约阅读时间需要 5 分钟。

题面

Description

求有多少种长度为 n 的序列 A,满足以下条件:
1 ~ n 这 n 个数在序列中各出现了一次
若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的
满足条件的序列可能很多,序列数对 10^9+7 取模。
Input
第一行一个数 T,表示有 T 组数据。
接下来 T 行,每行两个整数 n、m。
T=500000,n≤1000000,m≤1000000
Output

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

Sample Input
5

1 0

1 1

5 2

100 50

10000 5000

Sample Output
0

1

20

578028887

60695423

解题思路

  题目大概就是选\(m\)个,其他错位排列。那么答案显然为\(C_n^m*d[n-m]\)\(d[i]\)表示长度为\(i\)的错位排列方案数,然后刚开始预处理出\(d\)

代码

#include
#include
#include
#include
using namespace std;const int MAXN = 1000005;const int MOD = 1e9+7;typedef long long LL;inline int rd(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f?x:-x;}int T,n,m,d[MAXN],fac[MAXN],inv[MAXN];inline int fast_pow(int x,int y){ int ret=1; for(;y;y>>=1){ if(y&1) ret=(LL)ret*x%MOD; x=(LL)x*x%MOD; } return ret;}inline LL C(int x,int y){ if(y>x) return 0; return (LL)fac[x]*inv[y]%MOD*inv[x-y]%MOD; }int main(){ d[1]=0;d[2]=1;fac[0]=1;d[0]=1; for(int i=3;i<=1000000;i++) d[i]=(LL)(i-1)*(d[i-1]+d[i-2])%MOD; for(int i=1;i<=1000000;i++) fac[i]=(LL)fac[i-1]*i%MOD; inv[1000000]=fast_pow(fac[1000000],MOD-2); for(int i=1000000-1;~i;i--) inv[i]=(LL)inv[i+1]*(i+1)%MOD; T=rd(); while(T--){ n=rd(),m=rd(); printf("%lld\n",(LL)d[n-m]*C(n,m)%MOD); } return 0; }

转载于:https://www.cnblogs.com/sdfzsyq/p/10056881.html

你可能感兴趣的文章
javascript事件小结(事件处理程序方式)--javascript高级程序设计笔记
查看>>
WPF Visibility属性用法
查看>>
zoj 2334 Monkey King 左偏树+并查集
查看>>
删除博客园复制 python 代码时遗留的空格
查看>>
根据元素取两个list<T>不同
查看>>
Delphi 中的 XMLDocument 类详解(4) - 获取根目录下的元素数
查看>>
教你透彻了解红黑树
查看>>
dbf导入sqlserver
查看>>
管洪伟 130702010039 实验报告
查看>>
构建之法阅读笔记05
查看>>
纸上谈兵01 排序算法简介及其C实现
查看>>
哈夫曼树
查看>>
什么是提醒?
查看>>
AngularJS5.0 (第一篇)
查看>>
ORACLE基础
查看>>
redis-4.0.8 配置文件解读
查看>>
Ubuntu 16.04搭建原始Git服务器
查看>>
Ubuntu 16.04下没有/var/log/messages文件问题解决
查看>>
JSP指令
查看>>
[转]操作系统Unix、Windows、Mac OS、Linux的故事
查看>>