越狱[HNOI2008][Codevs1851]
2016-05-30 13:37
281 查看
题目描述 Description
监狱有连续编号为1...N 的 N 个房间,每个房间关押一个犯人,有 M 种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱输入描述 Input Description
输入两个整数 M,N 。 1<=M<=108,1<=N<=1012输出描述 Output Description
可能越狱的状态数,模 100003 取余样例输入 Sample Input
2 3样例输出 Sample Output
6数据范围及提示 Data Size & Hint
6 种状态为 (000)(001)(011)(100)(110)(111)分析
这个题目考虑可以越狱的情况并不容易,所以我们来考虑不可能发生越狱的情况。首先是对于 1 号房间的犯人,他的宗教有 m 种可能。
其次是对于 2 号房间的犯人,要使他不越狱,也就是宗教与第 1 号不同,故他的宗教有 m−1 种可能。
再对于 3 号房间的犯人,要使他不越狱,也就是宗教与第 2 号不同,故他的宗教也有 m−1 种可能。
...
对于 n 号房间的犯人,要使他不越狱,也就是宗教与第 n−1 号不同,故他的宗教也有 m−1 种可能。
所以,不可能发生越狱的情况发生越狱的情况共有 m∗(m−1)n−1 种可能,而所有的情况有 mn 种,故可能发生的越狱情况有 mn−m∗(m−1)n−1 种可能。这里用快速幂就可以了
代码
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; const LL Mod = 100003LL; LL n,m; LL mi(LL,LL); int main(){ scanf("%lld%lld",&m,&n); m %= Mod; printf("%lld",(Mod+mi(m,n)-(m*mi(m-1,n-1))%Mod)%Mod); return 0; } LL mi(LL x,LL y){ if(y == 1) return x; if(y == 2) return x*x%Mod; LL tmp; tmp = mi(x,y>>1); tmp = tmp*tmp%Mod; if(y&1) tmp = tmp*x%Mod; return tmp; }