快速幂小结

(本文不涉及取模运算……)

快速幂,顾名思义,就是快速地求幂运算。

现在要求x=yn的值,最朴素的解法:

int pow(int y, int n) {
    int result = 1;
    for (int i = 0; i < n; i++) {
        result *= y;
    }
    return result;
}

复杂度是O(n)

当n是偶数的时候,我们设n=2*m,则x=yn=y2*m=(ym)^2

当n是奇数的时候,我们设n=2*m+1,则x=yn=y2*m+1=y*(ym)^2

这样,我们就把复杂度从O(n)降到了O(n/2),递归下去,算法的复杂度就是O(log2n)……该怎么解释这个……其实我不会……

用递归实现比较容易理解,具体代码:

int quick_pow(int y, int n) {
    if (n == 0) return 1;
    if (n % 2 == 1) {
        // n是奇数 n=2*m+1
        // x = y^(2*m+1) = y*(y^m)^2
        int m = n / 2;
        int temp = quick_pow(y, m);
        return y * temp *temp;
    } else {
        // n是偶数 n=2*m
        // x = y^(2*m) = (y^m)^2
        int m = n / 2;
        int temp = quick_pow(y, m);
        return temp *temp;
    }
}

可以简化一下~~

int quick_pow(int y, int n) {
    if (!n) return 1;
    int temp = quick_pow(y, n >> 1);
    if (n & 1) return y * temp *temp;
    else return temp *temp;
}

非递归的版本也很容易理解啦

int quick_pow(int y, int n) {
    int result = 1;
    while (n > 0) {
        if (n % 2 == 1) {
            // y^n = y^(2*m+1) = y*(y^2)^m
            result *= y;
            // 接下来让y=y^2, n=m
            y = y * y;
            n = n / 2;
        } else {
            // y^n = y^(2*m) = (y^2)^m
            y = y * y;
            n = n / 2;
        }
    }
    return result;
}

简化一下~~~

int quick_pow(int y, int n) {
    int result = 1;
    while (n) {
        if (n & 1) result *= y;
        y = y * y;
        n >>= 1;
    }
    return result;
}

矩阵快速幂

待续...

时间: 2024-11-08 21:20:19

快速幂小结的相关文章

矩阵快速幂小结

矩阵 并不想扯什么高端线代的内容因为我也不会 定义 由$n \times m$个数$a_{ij}$排成的$n$行$m$列的数表称为$n$行$m$列的矩阵,简称$n \times m$矩阵. $$A =\begin{bmatrix}a_{11} & a_{12} & \dots a_{1m} \\ a_{21}, & \dots & \dots \\ a_{31}, & \dots & \dots \\ a_{41} & \dots & a_{

矩阵快速幂的一份小结

矩阵真是个好东西!虽然矩乘的复杂度有点难看... ... 这几天也做了不少矩阵题目,还是有几道好题目的.不过我打算从入门开始. 矩阵乘法:A[i][k]*B[k][j]=C[i][j];(A的第i行的每项依次乘以B的第j列的每项的和) 很显然这是一个n^3的算法,还是比较难看的. 代码就差不多是这样了. struct Matrix{int T[51][51];}; Matrix Mul(Matrix a,Matrix b,int I,int K,int J) { Matrix S=S0; for

【转】C语言快速幂取模算法小结

(转自:http://www.jb51.net/article/54947.htm) 本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余).在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快.计算范围更大的算法,产生了快速幂取模算法.我们先从简单的例子入手:求abmodc 算法1.直接设计这个算法: int ans = 1; for(int i =

uva11609(组合数学,快速幂)

先选人,再从这些人里选一个队长,方案总数:C(i,1)*C(n,i)(其中i从1到n)的总和. 这个公式显然不能在时限内暴力算出来,需要变形和推导出更简单的来. 用到组合数里面这个公式:C(n,k)*C(k,r)=C(n,r)*C(n-r,k-r)(其中r<=k) 一变换以后就可以推出最后结果就是n*(2^n-1),n比较大,所以再用下快速幂就好了. 这里从实际模型出发解释一下这个组合数公式: 有n个球,从中选k个,再从k个里选r个做上标记,有多少选法? 一种思路就是先选k个在从k个里选r个,结

【做题】SRM701 Div1 Hard - FibonacciStringSum——数学和式&矩阵快速幂

原文链接 https://www.cnblogs.com/cly-none/p/SRM701Div1C.html 题意:定义"Fibonacci string"为没有连续1的01串.现在,给出\(a,b\),定义一个"Fibonacci string"的权值为\(x^a y^b\),其中\(x\)为0的个数,\(y\)为1的个数. 要求对所有长度为\(n\)的"Fibonacci string"的权值求和,对\(10^9 + 7\)取模. \(n

矩阵快速幂刷题系列

来源自http://blog.csdn.net/chenguolinblog/article/details/10309423 hdu 1575 Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5587    Accepted Submission(s): 4200 Problem Description A为一个方阵,则Tr

快速幂取模(POJ 1995)

http://poj.org/problem?id=1995 以这道题来分析一下快速幂取模 a^b%c(这就是著名的RSA公钥的加密方法),当a,b很大时,直接求解这个问题不太可能 利用公式a*b%c=((a%c)*b)%c 每一步都进行这种处理,这就解决了a^b可能太大存不下的问题,但这个算法的时间复杂度依然没有得到优化 由此可以用快速幂算法优化: http://www.cnblogs.com/qlky/p/5020402.html 再结合取模公式: (a + b) % p = (a % p

HDU 1757 A Simple Math Problem (矩阵快速幂)

[题目链接]:click here~~ [题目大意]: If x < 10 f(x) = x. If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + -- + a9 * f(x-10); 问f(k)%m的值. [思路]:矩阵快速幂,具体思路看代码吧,注意一些细节. 代码: #include<bits/stdc++.h> using namespace std; typedef long long LL; const

快速幂及快速幂取模

快速幂顾名思义,就是快速算某个数的多少次幂.其时间复杂度为 O(log?N), 与朴素的O(N)相比效率有了极大的提高.——bybaidu 快速幂可以用位运算这个强大的工具实现. 代码: 1 int pow(int a,int b) 2 { 3 int ans=1; 4 while(b!=0) 5 { 6 if(b&1) 7 ans*=a; 8 a*=a; 9 b>>=1; 10 } 11 return ans; 12 } 快速幂取模需要记住一个定理:积的取模等于取模积的取模:算法是蒙