[HNOI2008]越狱

1008: [HNOI2008]越狱

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 5247  Solved: 2270
[Submit][Status][Discuss]

Description

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

Input

输入两个整数M,N.1<=M<=10^8,1<=N<=10^12

Output

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

Sample Input

2 3

Sample Output

6

HINT

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

 

   此题属于一道组合数学问题,我一开始还以为是DP。。。。

  所有的可能宗教信仰方案为:M^N,因为有N个监狱,每个监狱的犯人的宗教有M中选择

  不能越狱(相邻两个房间的人的宗教信仰不同)的方案为:M*(M-1)^(N-1),第一个监狱里的犯人可以有M个宗教选择,第二个监狱里的犯人可以有M-1中选择(保证和第一个监狱里的犯人不重复即可),同理,第三个监狱的犯人只需和第二个监狱里的不一样,也是M-1个选择,,,,以此类推,共N个监狱,除第一个监狱有M个选择,其余N-1个监狱只有M-1中选择,所以M*(M-1)^(N-1)

  于是最终的答案: [M^N-M*(M-1)^(N-1)]%100003

  由于N,M都比较大,所以借助了快速幂(讲解:www.cnblogs.com/CXCXCXC/p/4641812.html)

  中间有很多细节需要mod,处处mod,mod前想想对不对,还有((M^N)%mod-(M*(M-1)^(N-1))%mod)%mod有可能为负数,可以特判,若ans<0,ans+=mod 也可以((M^N)%mod+mod-(M*(M-1)^(N-1))%mod)%mod 即中间加个mod

 1 #include<bits/stdc++.h>

 2 using namespace std;

 3 typedef long long LL;

 4 const int mod=100003;

 5 LL M,N;

 6 LL ans;

 7 

 8 LL poww(LL a,LL b){

 9     LL base=a;

10     LL ans1=1;

11     while(b!=0){

12         if(b&1!=0){

13             ans1=ans1*base;

14             ans1=ans1%mod;

15         }

16         base=base*base;

17         base=base%mod;

18         b=b>>1;

19     }

20     return ans1%mod;

21 }

22 int main(){

23     cin>>M>>N;

24     ans=(poww(M,N)+mod-(M*poww(M-1,N-1))%mod)%mod;

25     cout<<ans;

26     return 0;

27 }

 

 

你可能感兴趣的:(2008)