[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 }

 

 

posted @ 2015-07-20 17:08  CXCXCXC  阅读(1025)  评论(0编辑  收藏  举报