数论(快速幂跟矩阵快速幂)

来源:互联网 发布:2018网络选美大赛报名 编辑:程序博客网 时间:2024/04/30 02:07

(A1B1+A2B2+ ... +AHBH)mod M.

高次幂取模

乘方取模问题  计算x的值, a^n=x(mod(m))。

显然 a^n = a*(a^n-1(mod(m)))(mod(m)).

    ans = 1;      for(int i = 0 ; i < n ; i++)      {           ans *= a;           ans %=m;      }  

最简单的代码如上。

这个算法的时间复杂度是O(n),假如给的n很大,一定会超时的。

下面就介绍一种快速幂算法

对指数n进行二分,那么显然有


a^n%m =  (a^n/2)^2%m (n为偶数)  (a^n/2)^2%m*a%m (n为奇数)。

这样就把时间复杂度从O(n)降到了O(logn)了

代码如下,代码适合m不超过int 的范围

long long quick_mod(long long a,long long b,long long m) /*快速幂算法,类似二分的思想*/  {      long long ans =  1;      while(b)      {          if(b&1)          {              ans*=a;              ans%=m;          }          b>>=1LL;          a*=a;          a%=m;      }      return ans;  }  

矩阵幂乘取模

要用到快速幂的思想。

唯一的区别就是整数乘法变成了矩阵乘法。

typedef struct  {      int m[Maxsize][Maxsize];  } Matrax;  Matrax multi(Matrax a,Matrax b) /*矩阵乘法*/  {      Matrax c;      for(int i = 0 ; i < n ; i++)      {          for(int j = 0 ; j < n ; j++)          {              c.m[i][j] = 0;              for(int k = 0 ; k < n ; k++)              {                  c.m[i][j]+= a.m[i][k]*b.m[k][j];              }              c.m[i][j]%=M;          }      }      return c;  }  Matrax power(int k) /*矩阵快速幂*/  {      Matrax p,ans;      ans = per;      p = a;      while(k)      {          if(k&1)          {              ans = multi(ans,p);          }          k>>=1;          p = multi(p,p);      }      return ans;  }