洛谷 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

posted @ 2018-07-07 16:21  露迭月  阅读(200)  评论(0编辑  收藏  举报