BISHI69 [HNOI2008]越狱¶
简单通过率 42.59%python3样例通过牛客 AC
讲解章节:组合数学
一句话
N 个房间各选 M 种宗教之一,求「存在相邻同宗教」的方案数 mod 100003。
解题思路¶
这题考什么¶
正难则反 + 乘法原理。
- 总方案数:每间房独立选,M^N;
- 不会越狱(任意相邻都不同)的方案:第 1 间任选 M 种, 之后每间只要和前一间不同,各有 M-1 种 -> M * (M-1)^(N-1);
- 答案 = M^N - M*(M-1)^(N-1),再模 P = 100003。
验算样例:M=2, N=3 -> 2^3 - 21^2 = 8 - 2 = 6 ✓ N = 1 时:M - M(M-1)^0 = M - M = 0,符合直觉(只有一间房谈不上相邻)。
数据规模与复杂度¶
M <= 1e8,N <= 1e12。指数到 1e12,必须快速幂 —— 用内置 pow(a, b, P), C 层实现,O(log N) 次模乘,一次询问微秒级。
坑在哪¶
- 不能用费马小定理把指数降到 N mod (P-1):M 可能是 P = 100003 的倍数 (M <= 1e8 完全够大),此时 M ≡ 0 (mod P),费马小定理的前提 gcd(M,P)=1 不成立, 降幂会算错。直接 pow(M % P, N, P) 就好,log(1e12) 才 40 层,没必要降;
- 相减可能得负数,最后统一 % P 转正(Python 的 % 自动给非负结果);
- M = 1 时 (M-1) = 0,pow(0, N-1, P) 在 N=1 时是 pow(0,0,P)=1, 答案 1 - 1*1 = 0;N >= 2 时是 0,答案 1 - 0 = 1,都正确;
- N 到 1e12 超过 int32。
参考实现¶
[:octicons-arrow-left-16: BISHI68](BISHI68.md) [BISHI70 :octicons-arrow-right-16:](BISHI70.md)