考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。
详细:错排
若满足 P(a, b) = P(a) * P(b),则有E(a, b) = E(a) + E(b)
给定正整数m,若用m除以两个整数a和b所得余数相同,称a和b对模m同余,记作a ∗ b ≡ 1(mod m)
举个栗子:假设要计算(a / b) % m,而b非常大,这里我们就可以把(a / b) 转化为(a * inv(b))
证明:
a * b ≡ 1(mod m)化简一下得到a * b + b * p = 1
假设a p不互质,则存在公约数d = gcd(a, p) > 1
原式中提出d得到:d * (a * b / d + b * p / d) = 1
移项:(a * b / d + b * p / d) = 1 / d
易知a, p能整除d,所以括号内定为整数,又因为d > 1,等式右边必为真分数,等式无解,因此a一定与p互质
#include
using namespace std;
int gcd(int a, int b) {
if(a < b) swap(a, b);
if(b == 0) return a;
return gcd(b, a % b);
}
int main() {
int n, m;
cin >> n >> m;
cout << gcd(n, m);
}
#include
using namespace std;
int x, y, q;
void exgcd(int a, int b) {
if(b == 0) {
x = 1;
y = 0;//如果gcd中有一项为0,则最大公约数为另一个不为0的数,并且只有唯一解
q = a;
}
else {
exgcd(b, a % b);//gcd(a, b) = gcd(b, a % b);
int temp = x;
x = y;
y = temp - a / b * y;
}
}
int main() {
int a, b;
cin >> a >> b;
if(a < b) swap(a, b);
exgcd(a, b);
printf("%d = %d * %d + %d * %d", q, a, x, b, y);
return 0;
}
//求gcd(a, b) = a * x + b * y的解
ax1 + by1 = bx2 + (a % b)y2;
因为a % b = a - (a / b) * b;
所以原式转化为:ax1 + by1 = bx2 + (a - (a / b) * b)y2;
拆开右式:bx2 + ay2 - (a / b) * by2;
因此:ax1 + by1 = ay2 + bx2 - (a / b) * by2 = ay2 - b(x2 - (a / b) * b);
根据恒等式:x1 = y2; y1 = x2 - (a / b) * b;