快速幂/快速幂矩阵 /快速幂取模

快速幂可以通过算式化简来有效的减少计算量;

 

例如8^5,如果不采用任何化简方式,则是8*8*8*8*8;

快速幂思想就是将指数进行分解,从而减少计算次数,参照的是二级制下的指数分离思想;

 

对于5,可以化为101二级制串,所以5=2^0+2^2;

 

所以8^5=8^1*8^4,从而有效地从五次计算化为了两次计算;

int quickpow(int a, int b) {
    int res = 1;//用于保存结果;
    int ans = a;//用来保存b的二进制次方;
    while (b != 0) {
        if (b % 2 == 1)
            res *= ans;
        ans *=ans;
        b /= 2;
    }
    return res;
}

 

其中值得注意的是ans*=ans一项,由于每一次循环都是原来a^2的平方,所以就相当于a^2*a^2;

 

矩阵幂和快速幂的思想相同,也是利用分解思想,将矩阵进行乘积进行分解,无非是乘法被矩阵乘法进行替代;

 

vector<vector<int>> multi(vector<vector<int>>m1, vector<vector<int>>m2) {
    vector<vector<int>> m3;
    m3.resize(n);
    for (int i = 0; i < n; i++) {
        m3[i].resize(n);
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                m3[i][j] += m1[i][k] * m2[k][j];
            }
        }
    }
    return m3;
}
 
vector<vector<int>> quckmatrix(vector<vector<int>> m) {
    vector<vector<int>> ans=m;
    vector<vector<int>> res;
    res.resize(n);
    for (int i = 0; i < n; i++) {
        res[i].resize(n);
    }
    for (int i = 0; i < n; i++) {
        //单位矩阵
        res[i][i] = 1;
    }
    while (k > 0) {
        //对k二进制进行操作;
        if (k % 2 == 1) {
            res = multi(res, ans);
        }
        k /= 2;
        ans = multi(ans, ans);
    }
    return res;
}

  

 

快速幂取模主要是多了个中途取模过程;数学推理不再赘述

 

int charge(int n,int m) {
	int base = n;
	int res = 1;
	while (m != 0) {
		if (m % 2 !=0) {
			res = res * base;
			res %= 1000;
		}
		base *= base;
		base %= 1000;
		m /= 2;
	}
	return res;
}

主要记住两点:

1.当二级制位数不为1.对res运算结果取模;

2.当base翻倍后,再次取模;

posted @ 2020-03-07 01:05  暮云林凌  阅读(199)  评论(0)    收藏  举报