[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; }
忘开longlong,忘用逆元,忘删调试信息,瞬间爆炸