[bzoj1008](HNOI2008)越狱(矩阵快速幂加速递推)

本文介绍了一种解决越狱状态计数问题的算法。该问题定义在一个包含N个连续编号房间的监狱中,每个房间关押一名犯人并可能信仰M种宗教之一。若相邻房间的犯人信仰相同宗教,则可能发生越狱。文章通过递推和矩阵快速幂的方法,求解可能的越狱状态数量,并提供了一个C++实现示例。

Description

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

Input

输入两个整数M,N.1<=M<=10^8,1<=N<=10^12

Output

可能越狱的状态数,模100003取余

Sample Input

2 3

Sample Output

6

HINT

6种状态为(000)(001)(011)(100)(110)(111)

分析

    注意一种状态即使有多处发生越狱也只能算一次。

    f(i)表示前i个监狱可能发生越狱的状态数,g(i)表示前i个监狱不发生越狱的状态数。容易得到转移方程:

        f(i) = f(i-1) + g(i-1);

        g(i) = (M-1)g(i-1);

     就可以用矩阵加速了。

 

ExpandedBlockStart.gif
 1 **************************************************************
 2     Problem: 1008
 3     User: AsmDef
 4     Language: C++
 5     Result: Accepted
 6     Time:0 ms
 7     Memory:804 kb
 8 ****************************************************************/
 9  
10 #include <cctype>
11 #include <cstdio>
12 using namespace std;
13 template<typename T>inline void getd(T &x){
14     char c = getchar(); bool minus = 0;
15     while(!isdigit(c) && c != '-')c = getchar();
16     if(c == '-')minus = 1, c = getchar();
17     x = c - '0';
18     while(isdigit(c = getchar()))x = x * 10 + c - '0';
19     if(minus)x = -x;
20 }
21 /*========================================================*/
22 const int mod = 100003;
23 typedef long long LL;
24 inline int powmod(LL x, LL k){
25     LL ans = 1;
26     while(k){
27         if(k & 1)ans = ans * x % mod;
28         x = x * x % mod;
29         k >>= 1;
30     }
31     return ans;
32 }
33 int main(){
34     #if defined DEBUG
35     freopen("test""r", stdin);
36     #else
37     //freopen("bzoj_1008.in", "r", stdin);
38     //freopen("bzoj_1008.out", "w", stdout);
39     #endif
40      
41     LL m, n;
42     getd(m), getd(n);
43     if(n == 1){putchar('0');return 0;}
44     printf("%lld", m * (powmod(m, n-1) + mod - powmod(m-1, n-1)) % mod);
45      
46     return 0;
47 }
矩阵快速幂

 

转载于:https://www.cnblogs.com/Asm-Definer/p/4368072.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值