zoukankan      html  css  js  c++  java
  • 快速幂和矩阵快速幂

    转载:快速幂和矩阵快速幂-模板

    快速幂的思想就是减少相乘的次数,将原本n-1次的相乘减小到(lg(n))的复杂度;

    a^b=(a^2)^(b/2)

    这个式子由于/是整除,所以得分奇偶的不同情况,偶数时仍然成立,奇数时需要再乘上一个a;

    所以快速幂就是将原本的以a为基本单位的连乘改成以a*a为单位的连乘;

    代码: 

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define ll long long 
     5 using namespace std;
     6 ll quickpow(ll a,ll n,ll mod)//计算的大多是要对mod;
     7 {
     8     int ans=1;
     9     while(n)
    10     {
    11         if(n&1)
    12             ans=ans*a%mod;
    13         a=a*a%mod;
    14         b/=2;
    15     }
    16     return ans;
    17 }
    18 int main()
    19 {
    20     int a,b,mod;
    21     cin>>a>>b>>mod;
    22     int ans=quickpow(a,b,mod);
    23     cout<<ans<<endl;
    24     return 0;
    25 }

    矩阵的快速幂是在这个的思想的基础上的,对矩阵进行更新;

    题目背景

    矩阵快速幂

    题目描述

    给定n*n的矩阵A,求A^k

    输入输出格式

    输入格式:

    第一行,n,k

    第2至n+1行,每行n个数,第i+1行第j个数表示矩阵第i行第j列的元素

    输出格式:

    输出A^k

    共n行,每行n个数,第i行第j个数表示矩阵第i行第j列的元素,每个元素模10^9+7

    输入输出样例

    输入样例#1: 
    2 1
    1 1
    1 1
    输出样例#1: 
    1 1
    1 1

    说明

    n<=100, k<=10^12, |矩阵元素|<=1000 算法:矩阵快速幂

    代码:

     1 #include<bits/stdc++.h>
     2 #define il inline
     3 #define ll long long
     4 using namespace std;
     5 const int mod=1e9+7;
     6 ll n,k;
     7 struct mat{ll a[102][102],r,c;};
     8 il mat mul(mat x,mat y)
     9 {
    10     mat p;
    11     memset(&p,0,sizeof(p));
    12     p.r=x.r,p.c=y.c;
    13     for(int i=0;i<x.r;i++)
    14         for(int j=0;j<y.c;j++)
    15             for(int k=0;k<x.c;k++)
    16     p.a[i][j]=(p.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
    17     return p;
    18 }
    19 il ll gi()
    20 {
    21     ll a=0;char x=getchar();bool f=0;
    22     while((x<'0'||x>'9')&&x!='-')x=getchar();
    23     if(x=='-')x=getchar(),f=1;
    24     while(x>='0'&&x<='9')a=a*10+x-48,x=getchar();
    25     return f?-a:a;
    26 }
    27 int main()
    28 {
    29     ios::sync_with_stdio(0);
    30     n=gi(),k=gi();
    31     mat p,ans;
    32     p.r=p.c=ans.r=ans.c=n;
    33     for(int i=0;i<n;i++)
    34         for(int j=0;j<n;j++)p.a[i][j]=gi(),ans.a[i][j]=p.a[i][j];
    35     k--;
    36     while(k)
    37     {
    38         if(k&1)ans=mul(ans,p);
    39         k>>=1;
    40         p=mul(p,p);
    41     }
    42     for(int i=0;i<n;i++){
    43         for(int j=0;j<n;j++)cout<<ans.a[i][j]<<' ';
    44         cout<<endl;
    45     }
    46     return 0;
    47 }

    不懂的可以点这里

  • 相关阅读:
    window.onload和DOMContentLoaded的区别
    存储
    JSONP的实现原理
    对于一个无线下拉加载图片的页面,如何给每个图片绑定事件
    事件冒泡
    通用的事件绑定函数
    拆解url的各部分
    如何检测浏览器的类型
    DOM节点操作
    es6基本用法
  • 原文地址:https://www.cnblogs.com/five20/p/7701944.html
Copyright © 2011-2022 走看看