wujiawei@HIT

ACM -- Fighting

常用链接

统计

最新评论

Something about the matrix

 

Something about the matrix

HOJ 2255 Not Fibonacci

题目大意:给出一个类似于Fibonacci的递推关系式f(n) = p * f(n-1) + q * f(n - 2).求出

我的做法根据S(n)f(n)的递推来构造一个5阶的矩阵:

              

               这样求方阵的n次幂的第一行与初始列向量的乘积再加和即可得到结果。

总结:锻炼递推啊。。

Code

 

 1#include <iostream>
 2#include <map>
 3#include <vector>
 4#define N 6
 5using namespace std;
 6struct matrix
 7{
 8    long long m[N][N];
 9}
E,S;
10matrix multiply(matrix x, matrix y, long long mod)
11{
12    matrix tmp;
13    int i, j, k;
14    for(i = 0; i < 5; i++)
15        for(j = 0; j < 5; j++)
16        {
17            tmp.m[i][j] = 0;
18            for(k = 0; k < 5; k++)
19            {
20                tmp.m[i][j] = ((tmp.m[i][j] + x.m[i][k] * y.m[k][j] % mod) + mod) % mod;
21            }

22        }

23    return tmp;
24}

25matrix mamod(matrix P, long long b, long long mod)
26{
27    matrix t = E,y = P;
28    while (b)
29    {
30        if (b & 1)
31            t = multiply(t, y, mod);
32        y = multiply(y, y, mod);
33        b>>=1;
34    }

35    return t;
36}

37long long a, b, p, q, s, e;
38long long Mod = 10000000;
39 
40long long cal(long long n)
41{
42    if(n == 1)
43        return a + b;
44    if(n == 0)
45        return a;
46    if(n < 0)
47        return 0;
48    matrix ret = mamod(S, n - 1, Mod);
49 
50    long long res = 0;
51    long long t[5= {a + b, a, b, a, 1};
52    for(int i(0); i < 5; i++)
53        res = ((res + t[i] * ret.m[0][i] % Mod) % Mod + Mod) % Mod;
54    return res;
55}

56int main()
57{
58    int test;
59    scanf("%d"&test);
60    for(int i(0); i < 5; i++)
61        for(int j(0); j < 5; j++)
62            E.m[i][j] = i == j ? 1 : 0;
63 
64    while(test--)
65    {
66        scanf("%lld %lld %lld %lld %lld %lld"&a, &b, &p, &q, &s, &e);
67 
68        memset(S.m, 0sizeof(S.m));
69        S.m[1][0= S.m[3][2= S.m[4][4= 1;
70        S.m[0][1= p + q;
71        S.m[0][2= p;
72        S.m[2][2= p;
73        S.m[2][3= q;
74        S.m[0][4= a * (1 - p) + b;
75        printf("%lld\n", ((cal(e) - cal(s - 1)) % Mod + Mod ) % Mod);
76    }

77    return 0;
78}

 

HOJ 2471 Learning English

题目大意:给出一些长度为2的单词集合S,问可以构造出多少个不同的单词,而且这些单词中的每两个相邻字母构成的2长度单词必须在S中。并给定所求单词的长度上限。

我的做法:问题可以转化为求长为L的通道的条数,每个字母为一个顶点,而且要将这些长度的数目加起来,可以构造矩阵,A为邻接阵,即求S = A + A2 + A3 + … + Ak 然后再 S中所有数字的和即可。

                  有两种方法:

1. 用分治的方法来进行二分,S = (E +A + A2 + A3 + … + Ak/2) *(E + Ak/2 )

2. 构造矩阵:

E为单位阵,O0阵,这样求这个矩阵的n次幂右上角的矩阵则为所求的和矩阵。用快速幂可求.

Code

 

 1#include <iostream>
 2#include <map>
 3#include <vector>
 4#define N 55
 5using namespace std;
 6struct matrix
 7{
 8    long long m[N][N];
 9}
E,S;
10matrix multiply(matrix x, matrix y, long long mod)
11{
12    matrix tmp;
13    int i, j, k;
14    for(i = 0; i < 52; i++)
15        for(j = 0; j < 52; j++)
16        {
17            tmp.m[i][j] = 0;
18            for(k = 0; k < 52; k++)
19            {
20                tmp.m[i][j] = ((tmp.m[i][j] + x.m[i][k] * y.m[k][j] % mod) + mod) % mod;
21            }

22        }

23    return tmp;
24}

25matrix mamod(matrix P, long long b, long long mod)
26{
27    matrix t = E,y = P;
28    while (b)
29    {
30        if (b & 1)
31            t = multiply(t, y, mod);
32        y = multiply(y, y, mod);
33        b>>=1;
34    }

35    return t;
36}

37long long s, e;
38long long Mod = 10000000;
39char as[213];
40int main()
41{
42    int test;
43    scanf("%d"&test);
44    for(int i(0); i < 52; i++)
45        for(int j(0); j < 52; j++)
46            E.m[i][j] = i == j ? 1 : 0;
47
48    while(test--)
49    {
50        scanf("%lld"&s);
51        memset(S.m, 0sizeof(S.m));
52        for (int i = 0; i < 26; i++)
53        {
54            S.m[i + 26][i + 26= 1;
55            S.m[i][i + 26= 1;
56        }

57        for(int i(0); i < s; i++)
58        {
59            scanf("%s"as);
60            S.m[as[0- 'a'][as[1- 'a'= 1;
61        }

62        scanf("%lld"&e);
63        matrix ret = mamod(S, e, Mod);
64
65        long long sum = 0;
66        for (int i = 0; i < 26; i++)
67        {
68            for (int j = 26; j < 52; j++)
69            {
70                sum += ret.m[i][j];
71                if (sum > 1000000)
72                    sum %= 1000000;
73            }

74        }

75        printf("%lld\n", sum - 26);
76    }

77    return 0;
78}

79

posted on 2010-08-23 10:22 wujiawei 阅读(249) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理