快速幂的理解

来源:互联网 发布:掌上贵金属软件下载 编辑:程序博客网 时间:2024/04/30 14:53
// 快速幂://顾名思义,快速幂就是快速算底数的n次幂。其时间复杂度为 O(log₂N), //与朴素的O(N)相比效率有了极大的提高#include <cstdio>#define MOD 1000000007int Pow(int a,int n) // recursive solution{    if(n == 0)        return 1;    int temp = Pow(a,n >> 1);    temp = temp * temp % MOD;    if(n & 1)    temp = temp * a % MOD;    return temp;}int Foo(int a,int n){    int temp = 1;    int y = a;    while(n)    {        if(n&1)            temp = temp * y % MOD;// 利用二进制的思想n^(10) = n^(B1010)                            // 出现n&1 此时y表示n^(2)  n^(2) * n^(8) = n^(10)        y = y * y % MOD;        n = n >> 1;    }    return temp;}int main(){    int a,b;    while(1)    {        scanf("%d%d",&a,&b);        printf("%d\n",Foo(a,b));        printf("%d\n",Pow(a,b));    }    return 0;}利用快速幂的思想求矩阵M的N的次方题目描述:https://hihocoder.com/problemset/problem/1504?sid=1074922在8x8的国际象棋棋盘上给定一只骑士(俗称“马”)棋子的位置(R, C),小Hi想知道从(R, C)开始移动N步一共有多少种不同的走法。  输入第一行包含三个整数,N,R和C。对于40%的数据, 1 <= N <= 1000000对于100%的数据, 1 <= N <= 1000000000 1 <= R, C <= 8输出从(R, C)开始走N步有多少种不同的走法。由于答案可能非常大,你只需要输出答案模1000000007的余数。样例输入2 1 1样例输出12#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>using namespace std;#define MOD 1000000007int Pow(int r,int c,int n){//Map to set from x to yconst int buff[8][2] = {{-1,+2},{-1,-2},{+1,+2},{+1,-2},{+2,-1},{-2,-1},{+2,+1},{-2,+1}};long long Map[64][64] = {0};long long Result[64] = {0};for(int i = 0;i < 8;i ++)for(int j = 0;j < 8;j ++){for(int k = 0;k < 8;k ++){   int x = i + buff[k][0];                int y = j + buff[k][1];                if(x >= 0 && x < 8 && y >= 0 && y < 8)                {                    Map[i * 8 + j][x * 8 + y] = 1;                }}}// Map ^ n  then sum the arrayfor(int i = 0;i < 64;i ++)        Result[i] = 1;while(n){if(n & 1){long long t[64] = {0};for(int i = 0;i < 64;i ++)  for(int j = 0;j < 64;j ++)  {  t[i] = t[i] + Map[i][j] * Result[j] % MOD;  }for(int i = 0;i < 64;i ++)Result[i] = t[i] % MOD;}int temp[64][64] = {0};for(int i = 0;i < 64;i ++)for(int j = 0;j < 64;j ++){long long t = 0;for(int k = 0;k < 64;k ++)t += Map[i][k] * Map[k][j] % MOD;temp[i][j] = t % MOD;}for(int i = 0;i < 64;i ++)for(int j = 0;j < 64;j ++)Map[i][j] = temp[i][j];n = n >> 1;}return Result[r * 8 + c];}int main(){int N,R,C;scanf("%d%d%d",&N,&R,&C);R --,C --;printf("%d\n",Pow(R,C,N));return 0;}
DFS计数问题,题目描述:https://hihocoder.com/problemset/problem/1560?sid=1156184  
#include <cstdio>#include <algorithm>#include <iostream>#include <cstring>using namespace std;#define MOD 1000000007long long aans = 0;long long A[10][10] = {0};long long AA[10][10] = {0};long long min_(long long n,long long m){    return n < m ? n : m;}void power(long long n){    while(n)    {        if(n&1)        {            long long tmpp[10][10] = {0};            for(int i = 0;i < 10;i ++)                for(int j = 0;j < 10;j ++)                    for(int k = 0;k < 10;k ++)                        tmpp[i][j] += A[i][k] * AA[k][j] % MOD;            for(int i = 0;i <= 9;i ++)                for(int j = 0;j <= 9;j ++)                A[i][j] = tmpp[i][j] % MOD;        }        long long tmp[10][10] = {0};        for(int i = 0;i < 10;i ++)               for(int j = 0;j < 10;j ++)        {            long long t = 0;            for(int k = 0;k < 10;k ++)                t += AA[i][k] * AA[k][j] % MOD;            tmp[i][j] = t % MOD;        }        for(int i = 0;i < 10;i ++)            for(int j = 0;j < 10;j ++)            AA[i][j] = tmp[i][j];        n = n >> 1;    }        return;}int main(){    long long n,m;    cin >> n >> m;    for(int i = 0;i <= 9;i ++)    {        for(int j = 0;j <= 9;j ++)        {            if(i == 0)                A[i][j] = 0;            else if(j == 0)            {                if(i == 0)                    A[i][j] = 0;                else if(i <= min_(9,m))                    A[i][j] = 1;            }            else            {                if(i*j <= m)                    A[i][j] = 1;            }        }    }    for(int i = 0;i <= 9;i ++)    {        for(int j = 0;j <= 9;j ++)        {            if(i == 0)            {                if(j <= min_(9,m))                    AA[i][j] = 1;            }            else if(j == 0)            {                if(i <= min_(9,m))                AA[i][j] = 1;            }            else            {                if(i*j <= m)                AA[i][j] = 1;            }        }    }    if(n == 1)        cout << min_(9,m);    else if(n == 2)    {         for(int i = 0;i <= 9;i ++)                for(int j = 0;j <= 9;j ++)                aans = aans + A[i][j] % MOD;            cout << aans % MOD << endl;    }    else{            power(n-2);            for(int i = 0;i <= 9;i ++)                for(int j = 0;j <= 9;j ++)                aans = aans + A[i][j] % MOD;            cout << aans % MOD << endl;        }    return 0;}


                                             
0 0
原创粉丝点击