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

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

 

思路:

  首先,要确定定m个位置,这些位置要求必须i=a[i],所以方案数是C(n,m),对于剩下的位置,要求i!=a[i],所以要求是一个错排。

p[0] = 0,p[1] = 1

p[i] = (i-1)*(p[i-1]+p[i-2])

 

代码

1 #include
2 #include
3 #include
4 #include
5 #include
6 7 using namespace std; 8 9 const int mod = 1e9+7;10 11 int f[1000100],p[1000100];12 13 inline int read() {14 int x = 0,f = 1;char ch=getchar();15 for (; ch<'0'||ch>'9'; ch=getchar()) if(ch=='-')f=-1;16 for (; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';17 return x*f;18 }19 20 void init() {21 f[0] = 1;22 for (int i=1; i<=1000000; ++i) f[i] = (1ll * f[i-1] * i) % mod;23 p[1] = 0;p[2] = 1;24 for (int i=3; i<=1000000; ++i) p[i] = (1ll * (i-1) * (p[i-1] + p[i-2])) % mod;25 }26 27 int inv(int a,int b) {28 int ans = 1;29 while (b) {30 if (b & 1) ans = (1ll*ans*a) % mod;31 a = (1ll * a * a) % mod;32 b >>= 1;33 }34 return ans % mod;35 }36 37 void solve(int n,int m) {38 if (n == m) {cout << "1\n";return ;}39 int t1 = inv(f[m],mod-2),t2 = inv(f[n-m],mod-2);40 int ans = (1ll * f[n] * t1) % mod;41 ans = (1ll * ans * t2) % mod;42 ans = (1ll * ans * p[n-m]) % mod;43 cout << ans << "\n";44 }45 46 int main() {47 int T = read();48 init();49 while (T--) {50 int n = read(),m = read();51 solve(n,m);52 }53 return 0;54 }

 

转载于:https://www.cnblogs.com/mjtcn/p/8709801.html

你可能感兴趣的文章
数字统计
查看>>
asp.net 文件操作小例子(创建文件夹,读,写,删)
查看>>
20180620小测
查看>>
7年,OpenStack从入门到放弃|送书
查看>>
部署mariadb高可用
查看>>
iptables设置规则
查看>>
聊聊setTimeout和setInterval线程
查看>>
计算机经典书箱
查看>>
随机给出三十道四则运算题目
查看>>
精品教程--Android实战系列源码与教程
查看>>
【动态规划】cf1034C. Region Separation
查看>>
android 打开系统相机,
查看>>
OC如何跳到系统设置里的各种设置界面
查看>>
UIView 的基础
查看>>
网络编程介绍
查看>>
pat 团体天梯赛 L2-012. 关于堆的判断
查看>>
四、构建Node Web程序
查看>>
【LeetCode】150. Evaluate Reverse Polish Notation
查看>>
远程连接服务器出现身份验证错误 要求的函数不受支持
查看>>
virtualenv模块使用
查看>>