题解 P4071 【[SDOI2016]排列计数】 (费马小定理求组合数 + 错排问题)
这题要用到错排,先理解一下什么是错排:
问题:有一个数集A,里面有n个元素 a[i]。求,如果将其打乱,有多少种方法使得所有第原来的i个数a[i]不在原来的位置上。
可以简单这么理解:
数集(初始)
1
2
3
4
5
6
错排转化后(一种情况):
2
1
4
3
6
5
于是,我们设f[i]为数集中有总共i个数时,其错排的方案数有多少。 那么,经过大量的手摸, 我们来求一下递推式:
f[0] = f[2] = 1, f[1] = 0,这些是显而易见的。当i大于3以后,假设存在一个数字k,我们手摸一下n出现在第k位的情况,发现会有以下两种:
1、数字n刚好在第k位,则我们要求的就是剩下n - 2个数的错排。即f[i - 2]\ 2、数字n不在第k位,则我们要求的就是n - 1个数的错排,即f[i - 1] 又由于我们的k是属于区间[1, n)的,又有n - 1种取值。\ 所以,我们要再乘上n - 1.即为 f[i] = (i - 1) * (f[i - 1] + f[i - 2])
回归本题 。 题目翻译:求在长为n的全排列中,第i位恰好是i,且满足条件的个数刚好有m个。 如果反过来看,就是把排列中的m个数抽出来,使得剩下的n - m个数全都不在自己的位置上。
那么答案就很明显了,ans = C(n, m) * f[n - m];
代码来一波:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 1000010
#define isdigit(c) ((c)>='0'&&(c)<='9')
const ll mod = (int)1e9 + ; inline ll read(){
ll x = ;
char c = getchar();
while(!isdigit(c)){
c = getchar();
}
while(isdigit(c)){
x = (x << ) + (x << ) + (c ^ '');
c = getchar();
}
return x;
} ll n, m;
struct node{
ll l, r;
} t[N]; ll inv[N], fac[N];
ll maxn = , maxm = ;
ll f[N]; ll pow(ll a,ll b){//求a的 b次方
ll s = ,temp = a;
while(b){
if(b & )s = (s * temp) % mod;
temp = (temp * temp) % mod;
b >>= ;
}
return s % mod;
} inline ll C(ll n, ll m){
if(n < m) return ;
else return inv[n] * fac[m] % mod * fac[n-m] % mod;
} void prepare(){
inv[] = fac[] = ;
for(int i = ;i <= maxn;i++)
inv[i] = inv[i-] * i % mod;
fac[maxn] = pow(inv[maxn], mod - ) % mod;//费马小定理求逆元
for(int i = maxn - ; i;i--)
fac[i] = fac[i + ] * (i + ) % mod; /*以上均是组合数求解*/
f[] = , f[] = , f[] = ;
for(int i = ;i <= maxn; i++){
f[i] = ((i - ) * (f[i - ] + f[i - ] % mod)) % mod; /*错排处理*/
}
return ;
} int main(){
ll T = read();
for(int i = ;i <= T; i++){
n = read(), m = read();
t[i] = (node){n, m};
maxn = max(maxn, n);/*先找最大值可以降低某些点的复杂度*/
}
prepare();
for(int i = ;i <= T; i++){
printf("%lld\n", C(t[i].l, t[i].r) * f[t[i].l - t[i].r] % mod); }
return ;
}
题解 P4071 【[SDOI2016]排列计数】 (费马小定理求组合数 + 错排问题)的更多相关文章
- 51nod1119(除法取模/费马小定理求组合数)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1119 题意:中文题诶- 思路:这题数据比较大直接暴力肯定是不 ...
- LightOJ 1419 – Necklace Polya计数+费马小定理求逆元
题意:给你n个珠子可以染成k种颜色,旋转后相同的视为一种,问共有几种情况 思路:开始按照一般的排列组合做发现情况太多且要太多运算,查了下发现此题是组合中Polya定理模板题- 学的浅只能大致一说公式S ...
- hihocoder #1698 假期计划 (排列组合+费马小定理+乘法逆元)
Description 小Ho未来有一个为期N天的假期,他计划在假期中看A部电影,刷B道编程题.为了劳逸结合,他决定先拿出若干天看电影,再拿出若干天刷题,最后再留若干天看电影.(若干代指大于0) 每 ...
- 洛谷——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 ...
- 【BZOJ】3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛(排列组合+乘法逆元+欧拉定理/费马小定理)
http://www.lydsy.com/JudgeOnline/problem.php?id=3398 以下牡牛为a,牝牛为b. 学完排列计数后试着来写这题,“至少”一词可以给我们提示,我们可以枚举 ...
- [ACM] hdu 3923 Invoker (Poyla计数,高速幂运算,扩展欧几里得或费马小定理)
Invoker Problem Description On of Vance's favourite hero is Invoker, Kael. As many people knows Kael ...
- Luogu P4071 [SDOI2016]排列计数
晚上XZTdalao给我推荐了这道数论题.太棒了又可以A一道省选题了 其实这道题也就考一个错排公式+组合数+乘法逆元 我们来一步一步分析 错排公式 通俗的说就是把n个1~n的数排成一个序列A,并使得所 ...
随机推荐
- Docker docker-compose 配置lnmp开发环境
1.安装docker yum -y install dockersystemctl start dockersystemctl enable docker 安装docker-compose https ...
- Ajax各参数介绍及使用
Ajax各参数介绍及使用 1. url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2. type: 要求为String类型的参数,请求方式(post或get)默认为get. ...
- 动态SQL各个标签作用以及注意事项详解
创建com.mybatis包,包含:UserMapper.xml和mybatis-config.xml UserMapper.xml代码: <?xml version="1.0&quo ...
- JVM之类加载器、加载过程及双亲委派机制
JVM 的生命周期 虚拟机的启动 Java 虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实 ...
- 全面解读 vue3.0
在此附上链接,在知乎上看到的,感觉说的很详细 https://zhuanlan.zhihu.com/p/46269528
- D. Caesar's Legions
\(状态很容易设计\) \(设dp[i][j][u][v]表示放了i个1兵种和j个2兵种\) \(然后u不会0说明末尾放了连续u个1兵种,v不为0说明末尾放了连续v个2兵种\) #include &l ...
- Kafka的参数调优
这篇文章主要说一下在生产过程中的kafka常用的调优参数, 首先kafka的版本是0.9.0.1,针对以下几个方面来说, 针对kafka的堆内存: 针对kafka的集群调优: kafka的的消息机制有 ...
- 【Spark】RDD的依赖关系和缓存相关知识点
文章目录 RDD的依赖关系 宽依赖 窄依赖 血统 RDD缓存 概述 缓存方式 RDD的依赖关系 RDD和它依赖的父RDD的关系有两种不同的类型,即窄依赖(narrow dependency) 和宽依赖 ...
- java-mysql类型对照
java mysql 数据类型对照 类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述 VARCHAR L+N VARCHAR java.lang. ...
- 错误 在应用程序级别之外使用注册为 allowDefinition='MachineToApplic
错误 在应用程序级别之外使用注册为 allowDefinition='MachineToApplication' 的节是错误的.如果在 IIS 中没有将虚拟目录配置为应用程序,则可能导致此错误. 如果 ...