##[$AcWing$ $1290$. 越狱](https://www.acwing.com/problem/content/1292/) ### 一、题目描述 监狱有连续编号为 $1$ 到 $n$ 的 $n$ 个房间,每个房间关押一个犯人。 有 $m$ 种宗教,每个犯人可能信仰其中一种。 如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。 求有多少种状态可能发生越狱。 **输入格式** 共一行,包含两个整数 $m$ 和 $n$。 **输出格式** 可能越狱的状态数,对 $100003$ 取余。 **数据范围** $1≤m≤10^8$ $1≤n≤10^{12}$ **输入样例** ```cpp {.line-numbers} 2 3 ``` **输出样例** ```cpp {.line-numbers} 6 ``` **样例解释** 所有可能的 $6$ 种状态为:$(000)(001)(011)(100)(110)(111)$。 ### 二、解题思路 本题可以采用容斥原理补集的思想。 考虑 $n$ 个犯人,$m$种宗教,如何安排不会导致犯罪。 第一个位置可以有 $m$ 个选择,则与第一个相邻的第二个位置就只有 $m−1$ 中选择。 考虑第 $i$ 个位置,则为了不和他左侧的 $i−1$ 位置发生冲突,一共有 $m-1$ 种选择。 ![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202311131426094.png) 因此不会导致犯罪的方案是: $m⋅(m−1)^{n−1}$ 则会导致犯罪的方案是:$m^n−m⋅(m−1)^{n−1}$ 计算一个数字的$n$次方,还要求取模,自然就需要使用快速幂~ 注意 注意减法取模可能会变成负数,那么我们要把他转化正数 $(a - b + mod) \% mod$ 即可 > 这里解释下:为什么取模+减法会出现负数呢?比如$MOD=10$ > $a=13,b=5$ > $ (a\%MOD -b \% MOD) \% MOD=13\%10 - 5 \%10=3-5=-2$ > 出现负数不是我们想的结果,那就在取模时加上$MOD$就行了 ### 三、实现代码 ```cpp {.line-numbers} #include using namespace std; #define int long long const int MOD = 100003; int qmi(int a, int b) { int res = 1; while (b) { if (b & 1) res = res * a % MOD; a = a * a % MOD; b >>= 1; } return res; } signed main() { int m, n; cin >> m >> n; cout << (qmi(m, n) - m * qmi(m - 1, n - 1) % MOD + MOD) % MOD << endl; return 0; } ```