[HNOI2008],[bzoj1008] 越狱(dp+组合数学)

题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1008

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[i]表示前i个监狱有多少种不发生越狱的状态,易得:dp[i]=dp[i-1]*(m-1) ,dp[1]=m; 即每个人只要保证与前面的人宗教不同。

  • 所以可得出答案为 ans=m^n-m*(m-1)^(n-1);

  • n太大怎么办?快速幂咯。

 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int mod=100003;
 7 
 8 long long n,m,ans;
 9 
10 long long po(long long a,long long b) {
11     long long sum=1,base=a;
12     while (b) {
13         if (b%2) sum=(sum*base+mod) % mod;
14         base=(base*base+mod) % mod;
15         b>>=1;
16     }
17     sum%=mod;
18     return sum;
19 }
20 
21 int main() {
22     scanf("%lld%lld",&m,&n);
23     ans=(m*(po(m,n-1)-po(m-1,n-1))+mod) % mod;
24     while (ans<0) ans+=mod;
25     printf("%lld\n",ans);    
26     return 0;
27 }

 

posted @ 2016-10-24 14:34  Aaron_w  阅读(149)  评论(0编辑  收藏