Fibonacci数列的矩阵运算
2014-04-16 21:36
162 查看
Fibonacci数列这一族的ACM层出不穷,屡屡坑爹,每次好容易看出是它结果又死在O(n)算法上
下面贴出来的是Fibonacci数列的O(log n)的矩阵算法
主要用到的思想便是矩阵的快速幂(ACM通常跟着坑爹的求模运算,这时候就看你数论的了)
这里需要提一下的就是
千万不要偷懒写成
不然真心逗了,不如直接算的,更慢更耗空间。
而对于写类的孩纸们,这里的重写等号函数并未申请空间,当是真正的二维数组的时候,记得delete其指针和正确的析构函数,不然内存怎么爆的都不知道
下面贴出来的是Fibonacci数列的O(log n)的矩阵算法
# include <iostream> typedef long long LL; typedef struct VALUEPAIR { LL PreviousVal; LL PresentVal; VALUEPAIR(const LL & x1, const LL & x2) { PreviousVal = x1; PresentVal = x2; } }ValuePair, VP; class Matrix { public: Matrix(); Matrix(const Matrix &); const Matrix operator=(const Matrix &); ~Matrix(); //void selfMutiply(); void operator*=(const Matrix &); LL getLtV() const; LL getLdV() const; LL getRtV() const; LL getRdV() const; VP operator*(const VP &); Matrix operator*(const Matrix &); friend std::ostream & operator<<(std::ostream &, const Matrix &); private: LL ltVal, rtVal, ldVal, rdVal; }; Matrix calculate(const int &); void getAns(const int &); int main(int argc, char const *argv[]) { int nTime = 0; while(1) { VP vp(0, 1); std::cout << "Input an integer pls\nnTime : "; while((std::cin >> nTime).fail()) { std::cout << "Error input\nInput an integer pls\nnTime :"; std::cin.clear(); std::cin.sync(); } getAns(nTime); } return 0; } Matrix calculate(const int &nTime) { //std::cout << nTime << std::endl; if(nTime == 1) { return Matrix(); } else { if(nTime % 2 == 1) { Matrix x, p = calculate(nTime / 2); p *= p; return x * p; } else { Matrix x = calculate(nTime / 2); return x * x; } } } void getAns(const int &nTime) { Matrix x = calculate(nTime); VP vp(0, 1); vp = x * vp; std::cout << vp.PresentVal << std::endl; } Matrix::Matrix() { this->ltVal = 0; this->ldVal = 1; this->rtVal = 1; this->rdVal = 1; } Matrix::Matrix(const Matrix &matrix) { //std::cout << "copy constructor" << std::endl; this->ltVal = matrix.ltVal; this->ldVal = matrix.ldVal; this->rtVal = matrix.rtVal; this->rdVal = matrix.rdVal; } const Matrix Matrix::operator=(const Matrix & matrix) { //std::cout << "operator =" << std::endl; this->ltVal = matrix.ltVal; this->ldVal = matrix.ldVal; this->rtVal = matrix.rtVal; this->rdVal = matrix.rdVal; return *this; } Matrix::~Matrix() { } void Matrix::operator*=(const Matrix &matrix) { int ltVal, ldVal, rtVal, rdVal; ltVal = this->ltVal * matrix.ltVal + this->rtVal * matrix.ldVal; ldVal = this->ldVal * matrix.ltVal + this->rdVal * matrix.ldVal; rtVal = this->ltVal * matrix.rtVal + this->rtVal * matrix.rdVal; rdVal = this->ldVal * matrix.rtVal + this->rdVal * matrix.rdVal; this->ltVal = ltVal; this->ldVal = ldVal; this->rtVal = rtVal; this->rdVal = rdVal; } LL Matrix::getLtV() const { return this->ltVal; } LL Matrix::getLdV() const { return this->ldVal; } LL Matrix::getRtV() const { return this->rtVal; } LL Matrix::getRdV() const { return this->rdVal; } VP Matrix::operator*(const VP &vp) { LL x = vp.PreviousVal, y = vp.PresentVal; return VP(x * this->getLtV() + y * this->getRtV(), x * this->getLdV() + y * this->getRdV()); } Matrix Matrix::operator*(const Matrix &matrix) { int ltVal, ldVal, rtVal, rdVal; ltVal = this->ltVal * matrix.ltVal + this->rtVal * matrix.ldVal; ldVal = this->ldVal * matrix.ltVal + this->rdVal * matrix.ldVal; rtVal = this->ltVal * matrix.rtVal + this->rtVal * matrix.rdVal; rdVal = this->ldVal * matrix.rtVal + this->rdVal * matrix.rdVal; this->ltVal = ltVal; this->ldVal = ldVal; this->rtVal = rtVal; this->rdVal = rdVal; return *this; } std::ostream & operator<<(std::ostream &stream, const Matrix &matrix) { stream << matrix.getLtV() << " " << matrix.getRtV() << std::endl; stream << matrix.getLdV() << " " << matrix.getRdV() << std::endl; }
主要用到的思想便是矩阵的快速幂(ACM通常跟着坑爹的求模运算,这时候就看你数论的了)
这里需要提一下的就是
Matrix calculate(const int &nTime) { //std::cout << nTime << std::endl; if(nTime == 1) { return Matrix(); } else { if(nTime % 2 == 1) { Matrix x, p = calculate(nTime / 2); p *= p; return x * p; } else { Matrix x = calculate(nTime / 2); return x * x; } } }
千万不要偷懒写成
Matrix calculate(const int &nTime) { //std::cout << nTime << std::endl; if(nTime == 1) { return Matrix(); } else { if(nTime % 2 == 1) { Matrix x; return x * calculate(nTime / 2) * calculate(nTime / 2); } else { return calculate(nTime / 2) * calculate(nTime / 2); } } }
不然真心逗了,不如直接算的,更慢更耗空间。
而对于写类的孩纸们,这里的重写等号函数并未申请空间,当是真正的二维数组的时候,记得delete其指针和正确的析构函数,不然内存怎么爆的都不知道
const Matrix Matrix::operator=(const Matrix & matrix) { //std::cout << "operator =" << std::endl; this->ltVal = matrix.ltVal; this->ldVal = matrix.ldVal; this->rtVal = matrix.rtVal; this->rdVal = matrix.rdVal; return *this; }
相关文章推荐
- 3.6 矩阵运算
- openCV中的常用矩阵运算
- 【python学习笔记】18:numpy数组函数与矩阵运算
- c语言练习题 4-2 矩阵运算
- HDU 2276-Kiki & Little Kiki 2(矩阵快速幂+位运算)
- C++矩阵库Eigen的仿Matlab矩阵运算
- Fibonacci数列(矩阵乘法快速幂)
- Java实现矩阵加减乘除及转制等运算功能示例
- C#的winform矩阵简单运算
- numpy教程 - 矩阵及其运算
- OpenCV矩阵运算
- 稀疏矩阵的各种基本运算并加法乘法
- 矩阵快速运算_总结
- 九度OJ 1164:旋转矩阵 (矩阵运算)
- 线性代数(四) :矩阵乘法的性质与分块矩阵的运算
- 用verilog表示两个4x4矩阵的乘法运算?及单个矩阵的求逆
- python矩阵运算
- ACM: 矩阵快速幂运算 数论题 poj 3…
- 矩阵的定义及其运算规则
- Java调用jama实现矩阵运算