P3197 [HNOI2008]越狱
Description
有 $ \ n \ $ 个房间,每个房间有一个犯人
犯人可以信仰$ \ \ m \ \ $种宗教其中的一种
若相邻的房间犯人的信仰相同,就有可能发生越狱
求越狱的情况总数
Solution
发现直接求越狱的情况总数并不好求
运用容斥原理,越狱的情况总数 $ \ = \ $ 所有的情况 $ \ - \ $ 不越狱的情况
所有的情况为$ \ m^n \ $
不越狱的情况为$ \ m \ * \ (m \ - \ 1)^{(n \ - \ 1)}$
快速幂求解相减即可
Code
#include <bits/stdc++.h>
using namespace std;
const int MOD = 100003;
typedef long long ll;
ll n, m;
// 总共状态:每格有 m 种选择, 共有 n 格,总共排列组合的数量是 m ^ n
// 合法状态: n 格 ,第一格有 m 种选择,第 2 ~ n 格有 (m - 1) 种选择 总数为 m * (m - 1) ^ (n - 1)
// m ^ n - m * (m - 1) ^ (n - 1)
// m * (m * (n - 1) - (m - 1) ^ (n - 1))
template <typename T>
void read(T &t) {
t = 0; T m = 1; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') m = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { t = (t << 3) + (t << 1) + (ch & 15); ch = getchar(); }
t *= m;
}
ll Pow(ll a, ll p) {
ll ans = 1; a %= MOD;
while(p) {
if(p % 2 == 1) ans = ans * a % MOD;
a = a * a % MOD; p >>= 1;
}
return ans % MOD;
}
int main() {
read(m), read(n);
ll A = Pow(m, n), B = (Pow(m - 1, n - 1) * (m % MOD)) % MOD;
printf("%lld\n", ((A + MOD) - B) % MOD);
return 0;
}