【BZOJ1008】【HNOI2008】越狱

原题传送门

Description

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

Input

输入两个整数M,N.1<=M<=108,1<=N<=1012

Output

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

Sample Input

2 3

Sample Output

6

Hint

6种状态为(000)(001)(011)(100)(110)(111)

Solution

\(f_{i}\)表示i个人有多少种越狱情况,那么容易推出\(f_{i} = f_{i-1} * (m)+m^{i}-f_{i-1} = f_{i-1} *(m-1) + m^ {i}\),显然这个很麻烦orz。
我们考虑取补集的情况,设\(f_{i}\)表示有i个人有多少种不越狱的情况,容易发现:

1.如果之前已经越狱了,由于无论如何都会越狱,贡献为0;
2.如果之前已经越狱了,我们只有与旁人信仰不同时才会越狱,贡献为\(f_{i-1}*(m-1)\)

因此,我们推出了这样的递推式:\(f_{1}=m ,f_{i} = f_{i-1}*(m-1)\)
用快速幂将所有的情况总数与\(f_{n}\)算出后相减即可。

Code

#include <stdio.h>
#define r register
#define mod 100003LL
#define ll long long
inline int pow(int a,ll k){
    int ans=1;
    for (; k; k>>=1,a=(1ll*a*a)%mod) if (k&1) ans=(1ll*ans*a)%mod;
    return ans;
}
int m; ll n;
int main(){
    scanf("%d%lld",&m,&n);int ans=pow(m,n);
    ans-=(1ll*m*pow(m-1,n-1))%mod; ans=(ans+mod)%mod; printf("%d",ans);
}
posted @ 2017-07-11 16:10  Melacau  阅读(168)  评论(0编辑  收藏  举报