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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章