HNOI 2008 越狱 快速幂+组合数学

题目描述

原题来自:HNOI 2008

监狱有连续编号为 1 到 n 的 n 个房间,每个房间关押一个犯人。有 m 种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。求有多少种状态可能发生越狱。

输入

输入两个整数 m 和 n。

输出

可能越狱的状态数,对 100003取余。

样例输入

2 3

样例输出

6

提示

样例说明

所有可能的 6 种状态为:{0,0,0},{0,0,1},{0,1,1},{1,0,0},{1,1,0},{1,1,1}。

对于全部数据,1≤m≤10^8,1≤n≤10^12。

题解:

快速幂+组合计数

这道题是正难则反,因为我们无法直接算出可能发生越狱的情况数,

那就将总方案数减去不可能发生越狱的情况数

(一)总的情况数

每个房间都有m种可能,一共n个房间

所以总的情况数为m^{n}

(二)不可能越狱的情况数

第一个房间有m种可能

第二个房间不能和第一个房间的宗教信仰一样,有m-1种可能

第三个房间不能和第二个房间的宗教信仰一样,有m-1种可能

以此类推

所以不可能发生越狱的情况数为:m*(m-1)^{n-1}

(三)发生越狱的情况数

发生越狱的情况数为:m^{n}-m*(m-1)^{n-1}

因为m和n都很大

所以总情况数和不可能越狱的情况数都用快速幂计算

代码:

#include<bits/stdc++.h>
#define mod 100003
#define ll long long
using namespace std;
ll Quick_pow(int a,int b)
{
    ll ans = 1;
    while(b != 0)
    {
        if(b & 1)
           ans = ans * a % mod;
        b >>= 1;
        a = ((a % mod) * (a % mod)) % mod;
    }
    return ans;
} 
int main()
{
    ll n,m;
    scanf("%d%d",&m,&n);
    cout<<((Quick_pow(m,n)%mod-(m * Quick_pow(m-1,n-1)))%mod+mod)%mod<<endl;
    return 0;
}

 

发布了57 篇原创文章 · 获赞 12 · 访问量 4823
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章