【题目描述】题目链接在此
原题来自:HNOI 2008
监狱有连续编号为 1 到 n 的 n 个房间,每个房间关押一个犯人。有 m 种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。求有多少种状态可能发生越狱。
【输入格式】
输入两个整数 m 和 n。
【输出格式】
可能越狱的状态数,对 100003 取余。
【样例输入】
2 3
【样例输出】
6
【样例说明】
所有可能的 666 种状态为:{0,0,0},{0,0,1},{0,1,1},{1,0,0},{1,1,0},{1,1,1}
【数据范围与提示】
对于全部数据,1≤m≤10^8,1,1≤n≤10^12。
思路:这道题的确也是快速幂,但是比转圈游戏更不好找到,因为他没有详细出现平方这样的字眼,但是仔细想想,还是能想出点头绪的,因为我们可以从越狱和不越狱的可能性出发,进行深度思考,其实我们只要能够理解到 m^n就是全部的可能性,只要能推出这个就一定能推出这是快速幂,而且也会离答案的公式越来越近,公式推导在代码里面。
【代码实现】
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define z 100003
typedef long long ll;
ll n,m;
ll power(ll x,ll y)
{
ll ans=1%z; x=x%z;
while(y>0)
{
if(y&1) ans=ans*x%z;
y=y>>1; x=x*x%z;
}
return ans;
}
int main()
{
scanf("%lld%lld",&m,&n);
ll a=power(m,n);
/*表示所有的可能方案,包括越狱和不越狱
比如说m为2,n为3,那么可能性为m^n=8,就是 0 0 0,0 0 1, 0 1 0, 0 1 1
1 0 0,1 0 1, 1 1 0, 1 1 1
ll b=m*power(m-1,n-1);
/*
不越狱的可能方案:
比如说:有三种宗教,那么不能越狱的就是 1 0 1 , 0 1 0 两种可能,就是m-1
那么如果有三个房间,第一个房间的宗教选择是1,
那么后面两个房间就是 1 0 , 0 1两种可能,就是n-1
*/
ll answer=((a-b)%z+z)%z;
/*
这个就是可以越狱的可能方案,mod是题目要求,+z是因为防止 -mod ,最后再mod就好了
*/
printf("%lld\n",answer);
return 0;
}
这道题只要理清楚总的可能性,不能越狱的可能性,可以越狱的可能性,就可以推出最终的公式,最后的答案可以连在一起输出,但是我为了理解和调试所以就分开输出了a和b,这个不太影响,洛谷上面也有这道题,挺好理解的,也蛮经典的。难度系数大概也是3.5吧,因为要理解这是快速幂和推公式,如果一开始就不能理解这是快速幂,那么这道题就做不出来。