51nod1121 机器人排队

该博客主要探讨了如何高效地计算阶乘和组合数,尤其是在求解最低18位的情况下。通过使用预处理矩阵和动态规划策略,实现了大整数模运算下的快速计算。文章中详细介绍了算法实现,包括add、mul、qpow等基本操作,并展示了在不同情况下的递归和非递归解法,对于理解和优化大整数计算具有指导意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题面

在这里插入图片描述
题目链接

解题思路

在这里插入图片描述
考虑如何求解阶乘,跟这篇题解类似,是求阶乘的最低十八位。组合数能够写成阶乘的形式。

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

#pragma GCC optimize(2)

typedef long long ll;
typedef __int128 Int;

Int add(Int a, Int b, Int mod) { return a + b >= mod ? a + b - mod : a + b; }
Int mul(Int a, Int b, Int mod) { return 1LL * a * b % mod; }
Int qpow(Int x, Int n, Int mod) { Int r = 1; for (; n; n >>= 1, x = mul(x, x, mod)) if (n & 1) r = mul(x, r, mod); return r; }
void exgcd(Int a, Int b, Int &x, Int &y) { b == 0 ? (x = 1, y = 0) : (exgcd(b, a % b, y, x), y -= a / b * x); }
Int rev(Int a, Int p) { Int x, y; exgcd(a, p, x, y); return (x + p) % p; }

struct node {
	Int s2[110][110];

	void init(Int k, Int mod) {
		s2[0][0] = 1;
		for (int i = 1; i <= k + 10; i++) {
			for (int j = 1; j <= i; j++) {
				s2[i][j] = add(s2[i - 1][j - 1], mul(j, s2[i - 1][j], mod), mod);
			}
		}
	}

	Int get(Int n, Int k, Int mod) {
		if (n == 0) return 0;
		Int res = 0;
		for (Int i = 1; i <= k && i <= n; i++) {
			Int sum = s2[k][i], flag = true;
			for (Int j = n - i + 1; j <= n + 1; j++) {
				if (j % (i + 1) == 0 && flag) sum = mul(sum, j / (i + 1), mod), flag = false;
				else sum = mul(sum, j, mod);
			}
			res = add(res, sum, mod);
		}
		return res;
	}

	Int g(Int t, Int d, Int p, Int k, Int mod) {
		if (t <= k) {
			Int res = 1;
			for (Int i = 0; i <= t; i++) res = mul(res, add(mul(i, p, mod), d, mod), mod);
			return res;
		}
		else {
			static Int dp[110], cd[110], cc[110], cp[110], cnt[110];
			cd[k - 1] = qpow(d, t - k + 2, mod);
			for (Int i = k - 2; i >= 0; i--) cd[i] = mul(d, cd[i + 1], mod);
			cc[0] = 1;
			for (Int i = 1; i < k; i++) cc[i] = get(t, i, mod);
			cp[0] = 1;
			for (Int i = 1; i < k; i++) cp[i] = mul(cp[i - 1], p, mod);
			cnt[0] = 0;
			for (Int i = 1; i < k; i++) cnt[i] = 0;
			dp[0] = 1; Int ma = 0;
			for (Int i = 1; i < k; i++) {
				dp[i] = 0;
				for (int j = 1, f = 1; j <= i; j++, f = -f) {
					Int r = mul(cc[j], mul(dp[i - j], cp[ma - cnt[i - j]], mod), mod);
					if (f > 0) dp[i] = add(dp[i], r, mod);
					else dp[i] = add(dp[i], mod - r, mod);
				}
				Int x = i; cnt[i] = ma;
				while (x % p == 0) x /= p, cnt[i]++, ma++;
				dp[i] = mul(dp[i], rev(x, mod), mod);
			}
			Int res = 0;
			for (int i = 0; i < k; i++) res = add(res, mul(cp[i - cnt[i]], mul(cd[i], dp[i], mod), mod), mod);
			return res;
		}
	}

	Int f(Int n, Int p, Int k, Int mod) {
		if (n < p) {
			Int res = 1;
			for (int i = 2; i <= n; i++) res = mul(res, i, mod);
			return res;
		}
		else {
			Int res = f(n / p, p, k, mod);
			for (int i = 1; i < p; i++) res = mul(res, g(n / p + (n % p >= i ? 0 : -1), i, p, k, mod), mod);
			return res;
		}
	}

	Int ans, cnt;

	void Fac(Int n, Int p, Int k, Int mod, Int op) {
		if (op == 1) ans = mul(ans, f(n, p, k, mod), mod);
		else ans = mul(ans, rev(f(n, p, k, mod), mod), mod);
		while (n > 0) cnt += n / p * op, n /= p;
	}

	void solve(Int n, Int m, Int p, Int k, Int mod) {
		init(k, mod);
		ans = 1, cnt = 0;
		Fac(n + m, p, k, mod, 1);
		Fac(n + 1, p, k, mod, -1); Fac(m, p, k, mod, -1);
		Int x = n - m + 1;
		while (x % p == 0) cnt++, x /= p;
		ans = mul(ans, x, mod);
	}
}a2, a5;

ll n, m;


int main() {
	//freopen("0.txt", "r", stdin);
	scanf("%lld%lld", &m, &n);
	if (m == 0) puts("1");
	else if (m > n) puts("0");
	else {
		Int n2 = qpow(2, 18, 1e20), n5 = qpow(5, 18, 1e20), nn = n2 * n5;
		a2.solve(n, m, 2, 18, n2);
		a5.solve(n, m, 5, 18, n5);
		Int r2 = a2.ans, r5 = a5.ans;
		Int c2 = a2.cnt, c5 = a5.cnt;
		r5 = mul(r5, qpow(rev(2, n5), c2, n5), n5);
		r2 = mul(r2, qpow(rev(5, n2), c5, n2), n2);
		Int t5 = Int(n2) * rev(n2, n5) % nn * r5 % nn;
		Int t2 = Int(n5) * rev(n5, n2) % nn * r2 % nn;
		Int r = (t5 + t2) % nn;
		r = mul(r, qpow(2, c2, nn), nn);
		r = mul(r, qpow(5, c5, nn), nn);
		printf("%lld\n", ll(r));
	}
	return 0;
}
### 戴维宁等效电路简介 在电气工程领域,戴维宁定理是一种用于简化复杂线性电路的技术。它允许工程师通过将复杂的网络转换为简单的等效形式来分析特定部分的行为。具体来说,任何由电压源、电流源以及电阻组成的线性二端网络都可以被替换为一个单一的电压源 \( V_{th} \) 和串联的一个阻抗 \( R_{th} \),这就是所谓的 **戴维宁等效电路**。 #### 如何计戴维宁等效参数? 为了构建戴维宁等效电路,需要确定两个主要参数: 1. **开路电压 (\(V_{th}\))**: 这是在负载断开的情况下测量到的两端之间的电压差。可以通过移除负载并求解剩余电路中的节点电压得到该值[^2]。 2. **等效阻抗 (\(R_{th}\))**: 它表示从外部看进去时整个网络呈现出来的总阻抗特性。通常的做法是将所有独立电源置零(理想电压源短接,理想电流源开路),然后计输入端口处看到的有效电阻或阻抗[^3]。 对于运放大器应用而言,当存在寄生电容如引用提到的情况(CG)[^1],这些额外元件也会影响最终形成的Thevenin模型的具体数值及其动态性能表现。 ```python import sympy as sp # Define symbols for calculation of Thevenin Equivalent Vs, Rs, RL = sp.symbols('Vs Rs RL') # Example expression representing part of a linear network I = Vs / (Rs + RL) # Solve for open-circuit voltage by setting RL to infinity V_th = I * RL.subs(RL, float('inf')) print(f"Thevenin Voltage: {V_th}") ``` 上述代码片段展示了如何利用Python与SymPy库来进行基本理论推导过程的一部分模拟操作——即寻找\(V_{th}\)的过程之一种方法论实例化展示而已并非针对实际硬件实现细节讨论范围内的脚本编写指南说明文档用途解释而已[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值