[bzoj1008](HNOI2008)越狱(矩阵快速幂加速递推)
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);
就可以用矩阵加速了。
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 }
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 }