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)
从题目里可以知道,N个房间M个宗教,可能产生的所有状态为A=N^M,要求出所有可能越狱的状态可能比较难,不如使用逆向思维,求所有不可能的越狱状态,可知只要相邻的房间宗教不同即可,故所有的不可能越狱状态为B=M*(M-1)*(M-1)...(M-1)=M*(M-1)^(N-1),那么答案就是A-B了,写个快速幂函数求出A,B即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; /*ll quickpower(ll m,ll n)//简写版本 { if(n==0) return 1; ll temp=quickpower(m,n>>1);// n>>1 == n/2 n的二进制右移几位就是除以2的n次方 temp=temp*temp%100003; if(n&1) temp=temp*m%100003;// n&1也就是取n的二进制最低位,判断n是否为奇数,是则为1 return temp%100003; }*/ ll quickpower(ll m,ll n)//更容易看懂的版本 { if(n==0) return 1; else { while((n&1)==0) { n>>=1; m=m*m%100003; } } int temp=m; n>>=1; while(n!=0) { m=m*m%100003; if((n&1)!=0) temp=temp*m%100003; n>>=1; } return temp; } int main() { ll m,n; cin>>m>>n; m%=100003; ll ans=quickpower(m,n); ans-=(m*quickpower(m-1,n-1))%100003; cout<<(ans+100003)%100003<<endl; return 0; }