数论——快速幂全解

1.基本原理

数据级别在1,000,000,就正常做不会超时,最简单的快速幂,根据 (a * b) % p = (a % p * b % p) % p

测试链接:http://acm.hdu.edu.cn/showproblem.php?pid=1021

#include <iostream>
#include <stdio.h>
using namespace std;

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        int f0=7,f1=11;
        int fn;
        for(int i=2;i<=n;i++){
            fn=(f0+f1)%3;
            f0=f1%3;
            f1=fn%3;
        }
        if(n<=1){
            cout<<"no"<<endl;
        }
        else{
            if(fn%3==0)
            cout<<"yes"<<endl;
            else
            cout<<"no"<<endl;
        }
    }
    return 0;
}

2.反复平方法



数据级别10亿,上一种就无法完成了,需要用另一种方法降低 n 的规模。

原理:比如 a^7=a^4*a^2*a^1=(a^2*a^2)*(a^1*a^1)*a^1。简单来说,就是求过的 a^i 的值不再求一遍,拿来直接用。

测试链接:http://acm.hdu.edu.cn/showproblem.php?pid=1061

式子中%号尽量多写,反正多写不会错,少写说不定超范围了,这是O(logn)级别的,10^9也不过就是30多次,不用担心时间的问题。

#include <iostream>
using namespace std;

int main() {
    int N;
    cin >> N;
    while (N--) {
        int n, res = 1;
        cin >> n;
        int a = n;
        while (n) {
            if (n & 1) {
                res = ((res % 10) * (a % 10)) % 10;
            }
            a = ((a % 10) * (a % 10)) % 10;
            n /= 2;
        }
        cout << res << endl;
    }
    return 0;
}

3.矩阵快速幂

首先要知道:矩阵乘法_百度百科,简单的说矩阵就是二维数组,数存在里面,相乘就是 横*竖,交叉位置是结果位置。

对着例子好理解些:

要注意的是:A的行数与B的列数必须相同才可以进行乘法

矩阵乘法:

//A :m行*n列;B:n行*m列
int** MatMulti(int **A, int **B, int m, int n) {
    int **C = new int*[n + 1];
    for (int i = 1; i <= n; i++) {
        C[i] = new int[n + 1];
        memset(C[i], 0, sizeof(int)*(n + 1));
    }

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= m; j++) {
            for (int k = 1; k <= n; k++) {
                if (A[i][k] == 0 || B[k][j] == 0)continue;
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
    return C;
}

完整测试代码:

#include <iostream>
using namespace std;

//A :m行*n列;B:n行*m列
int** MatMulti(int **A, int **B, int m, int n) {
    int **C = new int*[n + 1];
    for (int i = 1; i <= n; i++) {
        C[i] = new int[n + 1];
        memset(C[i], 0, sizeof(int)*(n + 1));
    }

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= m; j++) {
            for (int k = 1; k <= n; k++) {
                if (A[i][k] == 0 || B[k][j] == 0)continue;
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
    return C;
}
/*2 3
1 2 3
4 5 6
1 4
2 5
3 6*/
int main() {
    int **a, **b;
    int m, n;
    cin >> m >> n;
    a = new int*[m + 1];
    b = new int*[n + 1];
    for (int i = 1; i <= m; i++) {
        a[i] = new int[n + 1];
    }
    for (int i = 1; i <= n; i++) {
        b[i] = new int[m + 1];
    }

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> a[i][j];
        }
    }

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> b[i][j];
        }
    }

    int **c = MatMulti(a, b, m, n);
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= m; j++) {
            cout << c[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

哪里该用m,哪里该用n搞不太清除也没关系,矩阵快速幂只会用到方阵。

原文地址:https://www.cnblogs.com/czc1999/p/10111573.html

时间: 2024-10-28 14:33:21

数论——快速幂全解的相关文章

hdu-5698 瞬间移动(数论+快速幂)

题目链接: 瞬间移动 Problem Description 有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第nn行第mm列的格子有几种方案,答案对1000000007取模. Input 多组测试数据. 两个整数n,m(2<= n,m<=100000) Output 一个整数表示答案 Sample Input 4 5 Sample Output 10 题意: 思路: 跟那个只能向下和向右走有多

HDU 5318 The Goddess Of The Moon(矩阵快速幂详解)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5318 题面: The Goddess Of The Moon Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 800    Accepted Submission(s): 349 Problem Description Chang'e (嫦

数论——快速幂,模运算及快速幂求逆元

一.快速幂 原理: 快速幂的原理十分简单. ak=a2^0*a2^1*a2^2*…a2^x,其中k=20+21+22+…+2x. 这显然是正确的.因为任何一个数都可以表示成二进制. 接下去利用位运算实现即可. 代码实现 模板题链接:快速幂 代码模板如下:时间复杂度O(logk) int qmi(int a,int k,int p) { int res=1%p; while(k) { if(k&1)res=(long long)res*a%p; a=(long long)a*a%p; k>&g

数论-快速幂

快速幂:求 a^b % p 1 #include <iostream> 2 using namespace std; 3 4 typedef long long LL; 5 6 LL qmi(LL a, LL b, LL p){ 7 LL res = 1 % p; 8 while(b){ 9 if(b & 1)res = res * a % p; 10 a = a * a % p; 11 b >>= 1; 12 } 13 return res; 14 } 原文地址:http

数论——快速幂算法 a^b mod c

// 快速计算 (a ^ p) % m 的值 __int64 FastM(__int64 a, __int64 p, __int64 m){ if (p == 0) return 1; __int64 r = a % m; __int64 k = 1; while (p > 1) { if ((p & 1)!=0) { k = (k * r) % m; } r = (r * r) % m; p >>= 1; } return (r * k) % m; }

数论——快速幂(C++)

源代码: #include<cstdio>int m,n,q,ans=1;int main(){ scanf("%d%d%d",&m,&n,&q); //m的n次方,对q的取余运算. m%=q; //为避免m*m率先溢出,首当其冲,对其进行取余运算. while (n) { if (n%2) ans=ans*m%q; n/=2; m=m*m%q; } printf("%d",ans); return 0;}

BZOJ3560 DZY Loves Math V 数论 快速幂

原文链接http://www.cnblogs.com/zhouzhendong/p/8111725.html 题目传送门 - BZOJ3560 题意概括 给定n个正整数a1,a2,-,an,求 的值(答案模10^9+7). 1<=n<=10^5,1<=ai<=10^7. 题解 本人是蒟蒻. 可以看这位大佬的(给出链接) http://blog.csdn.net/popoqqq/article/details/42739963 代码 呵呵,调试的时候照着他的改,改的几乎一样-- #i

快速幂详解[二进制][十进制]+模板

xxx #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <string> #include <cstdio> #include <vector> #include <bitset> #include <cmath> #include <ctime> #inclu

hdu 4549 M斐波那契数列(快速幂 矩阵快速幂 费马小定理)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4549: 题目是中文的很容易理解吧.可一开始我把题目看错了,这毛病哈哈. 一开始我看错题时,就用了一个快速幂来解,不用说肯定wa,看题目的通过率也不高,我想会不会有啥坑啊.然而我就是那大坑,哈哈. 不说了,直接说题吧,先讨论k=1,2,3;时的解.这应该会解吧,不多说了: 从第四项开始f(4)=a^1+b^2;f(5)=a^2+b^3;f(6)=a^3+b^5......; 看出来了吧,a上的指数成斐波