數學雜技

預處理組合數

for (int i = 0; i <= N; ++i) {
        c[i][0] = c[i][i] = 1;
        for (int j = 1; j < i; ++j)
            c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % P;
}



擴展歐幾里得 ax + by = gcd(a, b)


LL exgcd(LL a, LL b, LL &x, LL &y) {
	if (b == 0) {
		x = 1;
		y = 0;
		return a;
	}
	LL r = exgcd(b, a % b, x, y);
	LL tmp = x;
	x = y;
	y = tmp - a / b * y;
	return r;
}


gcd(a, b) = gcd(b, a % b)

ax1 + by1 = gcd(a, b)

bx2 + (a % b)y2 = gcd(b, a % b)

a % b = a - a / b * b

ax1 + by1 = bx2 + ay2 - a / b * by2

ax1 + by1 = ay2 - b(x2 - a / b * y2)

x1 = y2

y1 = x2 - a / b * y2;


線性求逆元


void ready() {
	inv[0] = inv[1] = 1;
	for (int i = 2; i <= MaxNum; ++i) inv[i] = (P - P / i) * inv[P % i] % P;
}


i * inv[i] ≡ (P % i) * inv[P % i]≡ 1(mod P)

P % i = P - P / i * i

i  * inv[i] ≡ P * inv[P % i] - P / i * i * inv[P % i] (mod P)

inv[i] ≡ -P / i * inv[P % i] (mod P)

inv[i] = (P - P / i) * inv[P % i] % P

中國剩餘定理


LL CRT(LL a[], LL m[], LL n) {
	LL res = 0, M = 1, x, y;
	for (int i = 0; i < n; ++i) M *= m[i];
	for (int i = 0; i < n; ++i) {
		LL Mi = M / m[i];
		LL r = exgcd(Mi, m[i], x, y);
		res = (res + Mi * x % M * a[i] % M + M) % M;
	}
	return res;
}


Miller-Rabin && pollard-rho


const int TIMES = 9;

LL mul_mod(LL a, LL b, LL P) {
	LL res = 0;
	a = a % P;
	while (b) {
		 if (b & 1) {
		 	res += a;
			if (res > P) res -= P;
		 }
		 a <<= 1;
		 if (a > P) a -= P;
		 b >>= 1;
	}
	return res;
}

LL pow_mod(LL a, LL b, LL P) {
	LL res = 1;
<span style="white-space:pre">	</span>a = a % P;
	while (b) {
		if (b & 1) res = mul_mod(res, a, P);
		a = mul_mod(a, a, P);
		b >>= 1;
	}
	return res;
}

bool Miller_Rabin(LL n, int times) { //Miller_Rabin(n, TIMES);
	if (n == 2) return 1;
	if (n < 2 || !(n & 1)) return 0;
	LL b = n - 1;
	int cnt = 0;
	while ((b & 1) == 0) {
		 b >>= 1;
		 ++cnt;
	}
	srand(time(NULL));
	for (int i = 0; i < times; ++i) {
		LL a = rand() % (n - 1) + 1;
		LL x = pow_mod(a, b, n), y;
		for (int j = 0; j < cnt; ++j) {
			y = mul_mod(x, x, n);
			if (y == 1 && x != 1 && x != n - 1) return 0;
			x = y;
		}
		if (y != 1) return 0;
	}
	return 1;
}

LL factor[105];

int fac_cnt;

LL pollard_rho(LL n, int k) {
	LL x, y, r, cnt = 1, cycle = 2;
	srand(time(NULL));
	x = rand() % (n - 1) + 1;
	y = x;
	while (1) {
		++cnt;
		x = (mul_mod(x, x, n) + k) % n;
		r = __gcd(y - x, n);
		if (1 < r && r < n) return r;
		if (y == x) return n;
		if (cnt == cycle) {
			y = x;
			cycle <<= 1;
		}
	}
}

void Find_Factor(LL n, int k) { //Find_Factor(n, 199);
	if (n == 1) return;
	if (Miller_Rabin(n, TIMES)) {
		factor[fac_cnt++] = n;
		return;
	}
	LL p = n;
	while (p >= n) p = pollard_rho(p, --k);
	Find_Factor(p, k);
	Find_Factor(n / p, k);
}



待更新...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章