[bzoj1008] 越狱

Description

  监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种。如果
相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱

数据范围巨大,排除线性做法之后会想到O(1)做法。

首先,如果不考虑题目中的限制条件,那么,状态数为m^n。接下来我们考虑去掉其中不会越狱的状态。

越狱的条件是两个人的信仰相同(达成共识),所以相邻的两个人信仰不同就可以避免发生越狱。第一个人有m种宗教可以信仰,他的邻居(因为是第一个所以只有一个邻居)只有m-1种宗教可以信仰,而再往后第一个人的影响已经消失了所以第三个人还是可以选择m-1种宗教。那么会越狱的方案总数就是m*(m-1)^(n-1),第一个m是第一个人,后面的(m-1)^(n-1)是后面的人的方案,相乘就是总数。

由于一个数的幂并不能O(1)求,而线性求会TLE,所以需要用到快速幂。

#include<cstdio>
#include<cstring>
const int mo=100003;
typedef long long ll;
ll ksm(ll xx,ll yy)
{
    long long f=1;long long tmp=xx;
    while(yy)
    {
        if(yy&1) f=(f*tmp)%mo;
        tmp=(tmp*tmp)%mo;
        yy>>=1;
    }
    return f;
}
ll m,n,ans;
int main()
{
    scanf("%lld%lld",&m,&n);
    ans=(ksm(m,n)-ksm(m-1,n-1)%mo*m%mo+mo)%mo;
    printf("%lld\n",ans);
    return 0;
}
View Code

 

posted @ 2018-03-21 22:08  _hcy_a  阅读(46)  评论(0编辑  收藏