next_permutation的一些思考

字典序全排列:按字典序对给定序列排序

n ! / ( n 1 ! ∗ n 2 ! . . . n m ! ) n!/(n_1!*n_2!...n_m!) n!/(n1!n2!...nm!)
12344124341244344321
aabccaacbcaaccbccbaa

全排列数 = n ! / ( n 1 ! ∗ n 2 ! . . . n m ! ) n!/(n_1!*n_2!...n_m!) n!/(n1!n2!...nm!)
其中n为全排列的字母或数字总数, n 1 , n 2 , . . . , n m n_1,n_2,...,n_m n1,n2,...,nm为每个字母或数字出现的次数,除以它们阶层的积是为了除去因重复元素带来的重复排序。

c++库函数:
next_permutation:求字典序排序的下一个排列,若无下一个排列,则返回false

#include<algorithm>
bool next_permutation(iterator start, iterator end);

相应地有prev_permutation:求字典序排序的上一个排列,若无上一个排列,则返回false

#include<iostream>
#include<algorithm>
int q[3] = {1, 2, 3};
while(next_permutation(q, q+3))
{
	for(int i = 0;i <3 ;i++)
		cout << q[i] << ' ';
	cout << endl;
}

扩展问题一:求一个序列的不同的排列数量

res = n ! / ( n 1 ! ∗ n 2 ! . . . n m ! ) n!/(n_1!*n_2!...n_m!) n!/(n1!n2!...nm!)
由于 n ! n! n!一般都很大,大多数题目要求对res%MOD

乘法逆元:若整数 b,m 互质,并且对于任意的整数 a,如果满足 b ∣ a b|a ba,则存在一个整数 x,使得 a b ≡ a ∗ x ( m o d   m ) \frac{a}{b}≡a*x(mod\ m) baax(mod m),则称 x 为 b 的模 m 乘法逆元,记为 b − 1 ( m o d   m ) b^{−1}(mod\ m) b1(mod m)
b 存在乘法逆元的充要条件是 b 与模数 m 互质。当模数 m 为质数时, b m − 2 b^{m−2} bm2 即为 b 的乘法逆元。

费马定理:如果m是一个质数,且a不是m的倍数,则 a m − 1 ≡ 1 ( m o d   m ) a^{m-1}\equiv1 (mod\ m) am11(mod m)

a b ≡ a ∗ b − 1 ( m o d   m ) \frac{a}{b} \equiv a*b^{-1}(mod\ m) baab1(mod m)
a ≡ a ∗ b − 1 ∗ b ( m o d   m ) a \equiv a * b^{-1}*b(mod\ m) aab1b(mod m)
b − 1 ∗ b ≡ 1 ( m o d   m ) b^{-1}*b\equiv 1(mod\ m) b1b1(mod m)
如果m为质数,且b不是m的倍数,则逆元存在
由费马定理知,如果m为质数,且b不是m的倍数,则 b m − 1 ≡ 1 ( m o d   m ) b^{m-1} \equiv1(mod\ m) bm11(mod m)
b m − 2 ∗ b ≡ 1 ( m o d   m ) b^{m-2}*b \equiv 1(mod\ m) bm2b1(mod m)
b − 1 ≡ b m − 2 ( m o d   m ) b^{-1} \equiv b^{m-2}(mod\ m) b1bm2(mod m)

扩展问题二:给定一个排列,求该排列在全排列中的序号

leetcode 5720. 使字符串有序的最少操作次数
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值