[bzoj1008] 越狱

本文探讨了在一个由N个连续编号房间组成的监狱中,每个房间关押着一名可能信仰M种宗教之一的犯人,如何计算可能发生越狱的不同状态数量。通过数学分析,给出了一种利用快速幂算法实现高效计算的方法。

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

 

转载于:https://www.cnblogs.com/mordor/p/8620104.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值