【题目】
题目描述 Description
监狱有连续编号为 1 … n 1\dots n 1…n 的 n n n 个房间,每个房间关押一个犯人,有 m m m 种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱
输入描述 Input Description
输入两个整数 m m m, n n n。 1 ≤ m ≤ 1 0 8 , 1 ≤ n ≤ 1 0 12 1\le m\le10^8,1\le n\le10^{12} 1≤m≤108,1≤n≤1012
输出描述 Output Description
可能越狱的状态数,模 100003 100003 100003 取余
样例输入 Sample Input
2 3
样例输出 Sample Output
6
数据范围及提示 Data Size & Hint
6 6 6 种状态为 (000)(001)(011)(100)(110)(111)
【分析】
比较简单的一道题了吧
根据正难则反的思想,正着不好做,不如求出总数然后减掉反着的
由于每一间牢房都有 m m m 种选择,一共有 n n n 个牢房,所以根据乘法原理,易知总数为 m n m^n mn
那么现在就是求不会越狱的方案数
易知,第一间牢房有 m m m 种选择,以后的都只有 ( m − 1 ) (m-1) (m−1) 种,所以为 m × ( m − 1 ) n − 1 m\times (m-1)^{n-1} m×(m−1)n−1
所以最后的答案为
a
n
s
=
m
n
−
m
×
(
m
−
1
)
n
−
1
ans=m^n-m\times (m-1)^{n-1}
ans=mn−m×(m−1)n−1
那么用快速幂就可以了
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define Mod 100003
#define ll long long
using namespace std;
ll Power(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1)
ans=ans*a%Mod;
a=a*a%Mod;
b>>=1;
}
return ans;
}
int main()
{
ll m,n;
scanf("%lld%lld",&m,&n);
ll x=Power(m,n),y=m*Power(m-1,n-1)%Mod;
printf("%lld",(x-y+Mod)%Mod);
return 0;
}