当前位置:网站首页>【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。
边栏推荐
- 6133. Maximum number of packets
- ICLR 2022 Best Paper: Partial Label Learning Based on Contrastive Disambiguation
- 在CDH的hue上的oozie出现,提交 Coordinator My Schedule 时出错
- JAX-based activation function, softmax function and cross entropy function
- npm npm
- Additional Features for Scripting
- WEB安全基础 - - - XRAY使用
- recursion: method calls itself
- 6133. 分组的最大数量
- A brief analysis of mobile APP security testing in software testing, shared by a third-party software testing agency in Beijing
猜你喜欢

CDH6的Hue打开出现‘ascii‘ codec can‘t encode characters

架构基本概念和架构本质

Appears in oozie on CDH's hue, error submitting Coordinator My Schedule

在CDH的hue上的oozie出现,提交 Coordinator My Schedule 时出错

Flink Yarn Per Job - CliFrontend

Thymeleaf简介

伸展树的特性及实现

【MySQL系列】MySQL索引事务

Use Jenkins for continuous integration, this knowledge point must be mastered

async和await用法介绍
随机推荐
使用Jenkins做持续集成,这个知识点必须要掌握
2022还想上岸学习软件测试必看,测试老鸟的肺腑之言...
Solve the port to take up
Several interview questions about golang concurrency
Secondary Vocational Network Security Competition B7 Competition Deployment Process
在CDH的hue上的oozie出现,提交 Coordinator My Schedule 时出错
Is TCP reliable?Why?
在MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password YES) 拒绝访问问题解决
Thesis understanding [RL - Exp Replay] - Experience Replay with Likelihood-free Importance Weights
How do programmers solve online problems gracefully?
[LeetCode304周赛] 两道关于基环树的题 6134. 找到离给定两个节点最近的节点,6135. 图中的最长环
【MySQL系列】MySQL索引事务
Oracle database is set to read-only and read-write
经典文献阅读之--DLO
类型“FC<Props>”的参数不能赋给类型“ForwardRefRenderFunction<unknown, Props>”的参数。 属性“defaultProps”的类型不兼容。 不
UML diagram of soft skills
洞见云原生微服务及微服务架构浅析
FAST-LIO2代码解析(二)
问题解决方式了
ELK日志采集