矩阵乘法

1、模运算基本性质链接:https://my.oschina.net/u/572632/blog/268778

     应用到运算规则:(a * b) % p = (a % p * b % p) % p

2、由于乘法是满足结合律的,所以我们有:

  不妨将k[1]..k[j]划分的更好一点?

其中(k[1],k[2]...k[j])表示将n表示成二进制数后每一位的数字。上面这个公式同时满足这样一个性质:

3、代码如下

ulong[,] result = new ulong[2, 2];

string str = Convert.ToString(n, 2);

int Length = str.Length;
ulong[,,] arrs = new ulong[Length, 2, 2];
arrs[0, 0, 0] = 0;
arrs[0, 0, 1] = 1;
arrs[0, 1, 0] = 1;
arrs[0, 1, 1] = 1;
for (int j = 1; j < Length; j++)
{
arrs[j, 0, 0] = (arrs[j - 1, 0, 0] * arrs[j - 1, 0, 0] + arrs[j - 1, 0, 1] * arrs[j - 1, 1, 0]) % MOD;
arrs[j, 0, 1] = (arrs[j - 1, 0, 0] * arrs[j - 1, 0, 1] + arrs[j - 1, 0, 1] * arrs[j - 1, 1, 1]) % MOD;
arrs[j, 1, 0] = (arrs[j - 1, 1, 0] * arrs[j - 1, 0, 0] + arrs[j - 1, 1, 1] * arrs[j - 1, 1, 0]) % MOD;
arrs[j, 1, 1] = (arrs[j - 1, 1, 0] * arrs[j - 1, 0, 1] + arrs[j - 1, 1, 1] * arrs[j - 1, 1, 1]) % MOD;
}
var chars = str.Reverse().ToArray();
for (int j = Length - 1 - 1; j >= 0; j--)
{
short k = Convert.ToInt16(chars[j].ToString());
if (j == Length - 1 - 1)
{
result[0, 0] = arrs[j + 1, 0, 0];
result[0, 1] = arrs[j + 1, 0, 1];
result[1, 0] = arrs[j + 1, 1, 0];
result[1, 1] = arrs[j + 1, 1, 1];
}
if (k != 0)
{
ulong a00 = result[0, 0] * arrs[j, 0, 0] + result[0, 1] * arrs[j, 1, 0];
ulong a01 = result[0, 0] * arrs[j, 0, 1] + result[0, 1] * arrs[j, 1, 1];
ulong a10 = result[1, 0] * arrs[j, 0, 0] + result[1, 1] * arrs[j, 1, 0];
ulong a11 = result[1, 0] * arrs[j, 0, 1] + result[1, 1] * arrs[j, 1, 1];
result[0, 0] = a00 % MOD;
result[0, 1] = a01 % MOD;
result[1, 0] = a10 % MOD;
result[1, 1] = a11 % MOD;

}

}

 

posted @ 2016-10-27 15:06  木美琉璃  阅读(269)  评论(0)    收藏  举报