洛谷 P3197 [HNOI2008]越狱 解题报告
P3197 [HNOI2008]越狱
题目描述
监狱有连续编号为\(1…N\)的\(N\)个房间,每个房间关押一个犯人,有\(M\)种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱。
输入输出格式
输入格式:
输入两个整数 \(M,N\)
输出格式:
可能越狱的状态数,模100003取余
说明
\(1≤M≤10^8\)
\(1≤N≤10^{12}\)
我们发现,直接求发生越狱的状态不是不可能,但时间复杂度过不去,很难用矩阵乘法优化。
不妨反其道而行之,采用补集转换的思想
我们先求出所有可能的宗教分布,为\(M^N\)
然后减去所有不可能发生越狱的情况,为\(M*(M-1)^{N-1}\),即第一个房间有\(M\)种选择,其余房间因为要保证和前一个房间不同,所以只有\(M-1\)种选择
然后直接上快速幂即可
Code:
#include <cstdio>
#define ll long long
const ll mod=100003;
ll n,m,ans;
ll quick_pow(ll c,ll k)
{
ll f=1;
while(k)
{
if(k&1)
f=f*c%mod;
c=c*c%mod;
k>>=1;
}
return f;
}
int main()
{
scanf("%lld%lld",&m,&n);
ans=((quick_pow(m,n)-quick_pow(m-1,n-1)*m%mod)%mod+mod)%mod;
printf("%lld\n",ans);
return 0;
}
2018.7.7