当前位置:网站首页>【ACWing】230. 排列计数
【ACWing】230. 排列计数
2022-08-01 23:47:00 【记录算法题解】
题目地址:
https://www.acwing.com/problem/content/description/232/
求有多少种长度为 n n n的序列 A A A,满足以下条件: 1 ∼ n 1∼n 1∼n这 n n n个数在序列中各出现了一次。若第 i i i个数 A [ i ] A[i] A[i]的值为 i i i,则称 i i i是稳定的,序列恰好有 m m m个数是稳定的。由于满足条件的序列可能很多,所以请你将序列数对 1 0 9 + 7 10^9+7 109+7取模后输出。
输入格式:
第一行一个数 T T T,表示有 T T T组数据。
接下来 T T T行,每行两个整数 n n n、 m m m。
输出格式:
输出 T T T行,每行一个整数,表示求出的序列数对 1 0 9 + 7 10^9+7 109+7取模后的值。
数据范围:
T ≤ 500000 , n ≤ 1000000 , m ≤ 1000000 T≤500000,n≤1000000,m≤1000000 T≤500000,n≤1000000,m≤1000000
首先, k k k个数的错排问题的解 f [ k ] f[k] f[k]满足 f [ k ] = ( k − 1 ) ( f [ k − 1 ] + f [ k − 2 ] ) , f [ 1 ] = 0 , f [ 2 ] = 1 f[k]=(k-1)(f[k-1]+f[k-2]),f[1]=0,f[2]=1 f[k]=(k−1)(f[k−1]+f[k−2]),f[1]=0,f[2]=1。参考https://blog.csdn.net/qq_46105170/article/details/125235949。那么本题可以分步骤,先取 m m m个数,方案为 ( n m ) n\choose m (mn)个,剩下的 n − m n-m n−m个数做错排即可。所以答案就是 ( n m ) f [ n − m ] {n\choose m} f[n-m] (mn)f[n−m] f f f值可以打个表,阶乘的值也可以打个表。由于 ( n m ) = n ! m ! ( n − m ) ! {n\choose m}=\frac{n!}{m!(n-m)!} (mn)=m!(n−m)!n!,而 p = 1 0 9 + 7 p=10^9+7 p=109+7是个素数,从而 a a a模 p p p的逆元可以用费马小定理和快速幂来做。费马小定理为,若 p p p为素数, ( a , p ) = 1 (a,p)=1 (a,p)=1,则 a p − 1 ≡ a a p − 2 ≡ 1 ( m o d p ) a^{p-1}\equiv aa^{p-2}\equiv1(\mod p) ap−1≡aap−2≡1(modp),从而 a a a的逆元为 a p − 2 a^{p-2} ap−2。逆元可以用记忆化避免重复计算。代码如下:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6 + 10, P = 1e9 + 7;
long fac[N], f[N], inv[N];
int n, m;
long fast_pow(long x, int p) {
long res = 1;
while (p) {
if (p & 1) res = res * x % P;
x = x * x % P;
p >>= 1;
}
return res;
}
long inverse(int i) {
if (~inv[i]) return inv[i];
return inv[i] = fast_pow(fac[i], P - 2);
}
long comb(int n, int m) {
return fac[n] * inverse(m) % P * inverse(n - m) % P;
}
int main() {
memset(inv, -1, sizeof inv);
f[0] = 1, f[1] = 0;
fac[0] = fac[1] = 1;
for (int i = 2; i < N; i++) {
f[i] = (i - 1) * (f[i - 1] + f[i - 2]) % P;
fac[i] = fac[i - 1] * i % P;
}
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
printf("%ld\n", comb(n, m) * f[n - m] % P);
}
}
预处理时间复杂度 O ( N ) O(N) O(N)( N N N为 n n n数据范围),每次询问时间 O ( log P ) O(\log P) O(logP), P = 1 0 9 + 7 P=10^9+7 P=109+7。
边栏推荐
- Thymeleaf简介
- 机器学习文本分类
- numpy.unique
- 6134. 找到离给定两个节点最近的节点-力扣双百代码
- 数据机构---第五章树与二叉树---二叉树的概念---应用题
- WEB安全基础 - - - XRAY使用
- The monthly salary of the test post is 5-9k, how to increase the salary to 25k?
- 6133. Maximum number of packets
- Leetcode 129求根节点到叶节点数字之和、104二叉树的最大深度、8字符串转换整数(atoi)、82删除排序链表中的重复元素II、204二分查找、94二叉树的中序遍历、144二叉树的前序遍历
- C语言——分支语句和循环语句
猜你喜欢
【MySQL系列】 MySQL表的增删改查(进阶)
cmd command
检查 Oracle 版本的 7 种方法
Docker实践经验:Docker 上部署 mysql8 主从复制
在CentOS下安装MySQL
在MySQL中使用MD5加密【入门体验】
架构基本概念和架构本质
Thesis understanding [RL - Exp Replay] - Experience Replay with Likelihood-free Importance Weights
Share an interface test project (very worth practicing)
使用Ganache、web3.js和remix在私有链上部署并调用合约
随机推荐
WEB安全基础 - - - XRAY使用
YOLO等目标检测模型的非极大值抑制NMS和评价指标(Acc, Precision, Recall, AP, mAP, RoI)、YOLOv5中[email protected]与
@Scheduled注解详解
color transparency parameter
Appears in oozie on CDH's hue, error submitting Coordinator My Schedule
检查 Oracle 版本的 7 种方法
获取小猪民宿(短租)数据
CDH6 Hue to open a "ASCII" codec can 't encode characters
6132. All the elements in the array is equal to zero - quick sort method
中职网络安全竞赛B7比赛部署流程
thinkphp漏洞总结
仿牛客网项目第三章:开发社区核心功能(详细步骤和思路)
Access the selected node in the console
UML diagram of soft skills
递归:方法调用自身
类型“FC<Props>”的参数不能赋给类型“ForwardRefRenderFunction<unknown, Props>”的参数。 属性“defaultProps”的类型不兼容。 不
工作5年,测试用例都设计不好?来看看大厂的用例设计总结
[C language advanced] file operation (2)
【MySQL篇】初识数据库
[LeetCode304 Weekly Competition] Two questions about the base ring tree 6134. Find the closest node to the given two nodes, 6135. The longest cycle in the graph