矩阵乘法

矩阵相乘与矩阵快速幂

2011年5月19日 没有评论
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#define CLR(arr,val) memset(arr,val,sizeof(arr))
const int MAX=100;
struct Matrix;
int mod=1000007;
struct Matrix
{
     Matrix(){}
     void init( int r, int c) //初始为全零矩阵
     {
         row=r;col=c;CLR(data,0);
     }
     void init( int size) //初始为单位矩阵
     {
         row=size;col=size;CLR(data,0);
         for ( int i=0;i!=size;i++) data[i][i]=1;
     }
 
     int data[MAX][MAX];
     int row,col;
     const Matrix& pow ( int m);
};
Matrix ret,temp,pret;
const Matrix& operator*( const Matrix& m1, const Matrix &m2)
{
     ret.init(m1.row,m2.col);
     for ( int i=0;i!=m1.row;i++)
         for ( int j=0;j!=m1.col;j++)
             if (m1.data[i][j]) for ( int k=0;k!=m2.col;k++)
                 if (m2.data[j][k]) ret.data[i][k]=(ret.data[i][k]+(( long long )m1.data[i][j]*m2.data[j][k]))%mod;
     return ret;
}
const Matrix& Matrix:: pow ( int m)
{
     temp=* this ;
     pret.init(row);
     while (m)
     {
         if (m&1)
             pret=temp*pret;
         temp=temp*temp;
         m>>=1;
     }
     return pret;
}

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 模板 标签:

【hdu 2276】【NYOJ 300】Kiki & Little Kiki 2 (矩阵计算)

2011年5月17日 没有评论

题意:
有一些灯,连成一个圏,编号成1~n,给你所有灯的初始状态(亮或者灭),对这些灯进行k(k<=10^8)次以下操作:
如果某个灯左边的那个灯是亮着的,就改变该位置的灯的状态,如果左边那个灯是灭的,则不需要对该处的灯进行改变。
求k次操作后灯的状态。

思路:
前两天做了一堆矩阵的题,今天一看这题直接想到了矩阵。
执行一次这种操作相当于是在mod 2的情况下用原状态乘以一个矩阵A,然后执行k次相当于乘了k次A矩阵,利用结合律,可知这相当于是原状态矩阵(一行n列)乘以矩阵A的k次方(需要利用矩阵快速幂算法)。

现在剩下的就是如何求矩阵A了,考虑一个比较简单的情况:
1 0 1 转化过后应该是 0 1 1
比较简单的可以看出应该让原矩阵乘以

1 1 0
0 1 1
1 0 1

然后对二取余即可。也就是说矩阵A是在一个单位矩阵的基础上,把单位主对角线矩阵上面的一行也都置成1即可(由于题目中说灯是循环放置的,所以最左边一列最下一行应该是1)

之后就比较水了。。

需要注意的是,其实这个可以设置成bool型的,乘法改成“与”,加法改成“异或”即可,这样可以不需要对2取余了。 阅读全文…

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 其它算法 标签:

【POJ 3735】Training little cats(矩阵运算)

2011年5月14日 没有评论

题意:
Facer要训练他的n个小猫(n<=100),他决定给他们几种指令:
一、让第i号小猫去拿一个果子
二、让第i号小猫吃掉自己所有的果子
三、让第i号小猫与第j号小猫交换所有的果子
然后Facer指定了一系列的指令(不超过100个)之后 ,决定让小猫把们这些动作执行很多遍(不超过10亿遍)
最后,问你每个小猫拥有的果子数量。

思路:
如果直接去执行100*10亿条指令,毫无疑问会超时。
然后考虑可以先把100条指令合成一条指令,于是想到可以用矩阵运算来实现。
构造一个1行n+1列的矩阵A,其中前n列都表示小猫拥有的果子数,最后一列置为1。则
以n=3为列,假设某一时刻,小猫们拥有的果子数量分别为a,b,c,则
三种操作分别对应下面三种矩阵乘法运算:

第一种操作:

第二种操作:

第三种操作

然后,由于矩阵乘法具有结合律,可以把后面100个操作结合成一个操作。然后,算出的矩阵要执行多少遍就求这个操作矩阵的多少次方就可以了。求次方的时候需要用到矩阵的快速幂方法。

这道题最后算出的结果可能会很大,需要用long long.

另外,有一个优化,不用优化一般会超时的,就是判断一下相乘的两个矩阵里是不是都不是0,如果有一个是0就不再计算乘法。
阅读全文…

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 算法 标签:

【POJ 3233】Matrix Power Series(矩阵计算)

2011年5月13日 没有评论

题意:已知矩阵A,求A^1+A^2+A^3+…+A^k。其中k<=2^31。

思路:

先看matrix67的讲解:

这道题两次二分,相当经典。首先我们知道,A^i可以二分求出。然后我们需要对整个题目的数据规模k进行二分。比如,当k=6时,有:
A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3) + A^3*(A + A^2 + A^3)
应用这个式子后,规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3,即可得到原问题的答案。

但在其他人的回复中,我找到了另一种方法,并按该种方法写出了代码,先把方法引用过来:

构造一个矩阵
A I
O I
自乘后
A^2 I+A
O I
乘3次为
A^3 I+A+A^2
O I
这样应该会更快吧,直接二分一下。

也就是说,把原矩阵的右方与右下方都添加上一个大小与A相同的单位矩阵(主对角线元素为1,其它元素为0的矩阵),原矩阵下方添加一个大小与A相同的全0的矩阵,然后求该矩阵的k+1次方(k比较大,利用矩阵快速幂算法可在log k的时间内求解),最后把算出的结果取右上角的矩阵减去一个单位矩阵即可得到答案。
阅读全文…

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 算法 标签:

矩阵快速幂

2011年5月13日 没有评论

这是matrix67十个利用矩阵乘法解决的经典题目中的第二个题目,思路比较简单,由于之前写过一个大数计算的快速幂,和这个基本上用的相同的方法,所以不一会就写出来了。
具体方法matrix大牛的博客中如是写道:

由于矩阵乘法具有结合律,因此A^4 = A * A * A * A = (A*A) * (A*A) = A^2 * A^2。我们可以得到这样的结论:当n为偶数时,A^n = A^(n/2) * A^(n/2);当n为奇数时,A^n = A^(n/2) * A^(n/2) * A (其中n/2取整)。这就告诉我们,计算A^n也可以使用二分快速求幂的方法。例如,为了算出A^25的值,我们只需要递归地计算出A^12、A^6、A^3的值即可。根据这里的一些结果,我们可以在计算过程中不断取模,避免高精度运算。

我实现的代码如下:
阅读全文…

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值