You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

##AcWing 1290. 越狱

一、题目描述

监狱有连续编号为 1nn 个房间,每个房间关押一个犯人。

m 种宗教,每个犯人可能信仰其中一种。

如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。

求有多少种状态可能发生越狱。

输入格式 共一行,包含两个整数 mn

输出格式 可能越狱的状态数,对 100003 取余。

数据范围 1≤m≤10^8 1≤n≤10^{12}

输入样例

2 3

输出样例

6

样例解释 所有可能的 6 种状态为:(000)(001)(011)(100)(110)(111)

二、解题思路

本题可以采用容斥原理补集的思想。

考虑 n 个犯人,m种宗教,如何安排不会导致犯罪。

第一个位置可以有 m 个选择,则与第一个相邻的第二个位置就只有 m1 中选择。

考虑第 i 个位置,则为了不和他左侧的 i1 位置发生冲突,一共有 m-1 种选择。

因此不会导致犯罪的方案是: m⋅(m1)^{n1}

则会导致犯罪的方案是:m^nm⋅(m1)^{n1}

计算一个数字的n次方,还要求取模,自然就需要使用快速幂~

注意 注意减法取模可能会变成负数,那么我们要把他转化正数 (a - b + mod) \% mod 即可

这里解释下:为什么取模+减法会出现负数呢?比如MOD=10 a=13,b=5 (a\%MOD -b \% MOD) \% MOD=13\%10 - 5 \%10=3-5=-2 出现负数不是我们想的结果,那就在取模时加上MOD就行了

三、实现代码

#include <bits/stdc++.h>
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;
}