监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱
输入格式
输入两个整数M,N.1<=M<=10^8,1<=N<=10^12
输出格式
可能越狱的状态数,模100003取余
数据范围和提示
6种状态为(000)(001)(011)(100)(110)(111)
Sample Input
2 3Sample Output
6
题意描述:给犯人的宗教信仰种数m(每个犯人可能信仰其中一种),以及他们的房间数量n(房间连续),如果相邻房间的犯人宗教相同,可能会越狱,求有多少种房间安排方式可能发生越狱(模100003取余)
解题思路:房间n连续,每个犯人信仰的宗教不确定,也就是每个房间都可以有m种信仰情况,所以房间的总共情况可以有m^n种,相邻犯人宗教相同的情况例举复杂,所以我们可以求所有相邻房间不存在犯人宗教相同的情况,第一个房间可以有m种情况,接下来的n-1个房间,每个房间都是m-1种(避免与前一个房间的犯人宗教相同),利用快速幂算,最后给它们相减
易错:数据大,还有每个计算结果都要对100003去余,最后相减取余的时候可能前面取的余数小于后面取的余数,要+100003(防止相减结果为负数),最后再对100003取一次余
AC:
#include<stdio.h>
long long fast(long long a,long long x)
{
long long res=1;
while(x)
{
if(x&1)//如果次幂的最后一位是1,表示这个地方需要乘
res=(res*a)%100003;
a=(a*a)%100003;//推算乘积,a^2 a^4 ………
x>>=1;//把刚才处理过的x的最后一位去掉
}
return res;
}
int main(void)
{
long long n,m,p,q;
scanf("%lld %lld",&m,&n);
p=fast(m,n);
q=(m*fast(m-1,n-1))%100003;//不越狱方案,第一个房间m种,其余m-1
printf("%lld\n",(p-q+100003)%100003);
return 0;
}