Number Theory - Quick power analysis

Fast power Binary exponentiation (Binary Exponentiation, also known as flat method), is one of Ο (logn)  calculated in time   tips, and calculated violence requires O (n)  time.

And this technique is often used in the calculation of the non-scene, since it can be applied in conjunction with any operation of law. Which obviously is that it can be applied to modular exponentiation, such as the meaning of the matrix power operation, we will discuss next.

General recursive method to achieve rapid power

long long binpow(long long a, long long b) {
  if (b == 0) return 1;
  long long res = binpow(a, b / 2);
  if (b % 2)
    return res * res * a;
  else
    return res * res;
}

Non-recursive method implementation

long long binpow(long long a, long long b) {
  long long res = 1;
  while (b > 0) {
    if (b & 1) res = res * a;
    a = a * a;
    b >>= 1;
  }
  return res;
}

Question 1: Rapid power modulo

Since no effect on the multiplication modulo operation, code for the following

long long binpow(long long a, long long b, long long m) {
  a %= m;
  long long res = 1;
  while (b > 0) {
    if (b & 1) res = res * a % m;
    a = a * a % m;
    b >>= 1;
  }
  return res;
}

Note: The Fermat's little theorem, if m  is a prime number, we can calculate X n-% (. 1-m) to accelerate the algorithmic process.

Question 2: Fast power matrix

template

struct Mat 
{ 
    LL m [ 101 ] [ 101 ]; 
}; // memory structure 
Mat A, e; // A is a matrix input, e is the output matrix 
Mat adder Mul (Mat X, Y Mat) 
{ 
    Mat C; 
    for ( int I = . 1 ; I <= n-; ++ I) {
         for ( int J = . 1 ; J <= n-; ++ J) { 
            cm & lt [I] [J] = 0 ; 
        } 
    } 
    for ( int I = . 1 ; I <= n-; ++ I) {
         for ( int j=1;j<=n;++j){
            for(int k=1;k<=n;++k){
                c.m[i][j] = c.m[i][j]%mod + x.m[i][k]*y.m[k][j]%mod;
            }
        }
    }
    return c;
}
Mat pow(Mat x,LL y)//矩阵快速幂
{
    Mat ans = e;
    while(y){
        if(y&1) ans = Mul(ans,x);
        x = Mul(x,x);
        y>>=1;
    }
    return ans;
}

 

1. Fibonacci number

Fibonacci recurrence of Number can be expressed in the form of a matrix multiplication

 

 

 

 

 So we can in O (logn) by matrix multiplication is calculated in the time Fibonacci number. Further, the former describes a formula can also be obtained by diagonalization of the matrix technique.

 2. The fixed length path computation

To a directed graph (right side of a), find any two u, v  between from u  to V  , of length k  number of paths.

We adjacency matrix M in the figure k - th power, then M ij of it represents from i to J k is the length of the number of paths. The complexity of the algorithm is O (n- . 3 logK).

3 . Accelerate the geometry of the operating point set

 

 

 Let's look at the impact of these three operations on coordinates:

  1. Shift Operation: Each dimensional coordinates plus a constant;
  2. Scale operation: the coordinates of each dimension is multiplied by a constant;
  3. Rotate operation: this is a bit complicated, we do not intend to delve into, but we can still use a linear combination to represent the new coordinates.

Can be seen, each transform may be expressed as a linear operation on the coordinates, thus, a conversion may be a 4X4  matrix represented by:

 

 

 

 Now, each operation is represented for a matrix transformation sequences can be used to represent the product matrix, and a k-th power Loop operation corresponds to take a matrix.

Such may be used   to calculate the transform matrix entire sequence of the ultimately formed O (mlog (k)). Finally it is applied to n on points, the total complexity of O (m + Mlog  (K)) .

Question 3: high accuracy and fast power

题目:从文件中输入 P(1000<P<3100000),计算  的最后 100 位数字(用十进制高精度数表示),不足 100 位时高位补 0。

#include <bits/stdc++.h>
using namespace std;
int a[505], b[505], t[505], i, j;
int mult(int x[], int y[])  // 高精度乘法
{
  memset(t, 0, sizeof(t));
  for (i = 1; i <= x[0]; i++) {
    for (j = 1; j <= y[0]; j++) {
      if (i + j - 1 > 100) continue;
      t[i + j - 1] += x[i] * y[j];
      t[i + j] += t[i + j - 1] / 10;
      t[i + j - 1] %= 10;
      t[0] = i + j;
    }
  }
  memcpy(b, t, sizeof(b));
}
void ksm(int p)  // 快速幂
{
  if (p == 1) {
    memcpy(b, a, sizeof(b));
    return;
  }
  ksm(p / 2);
  mult(b, b);
  if (p % 2 == 1) mult(b, a);
}
int main() {
  int p;
  scanf("%d", &p);
  a[0] = 1;
  a[1] = 2;
  b[0] = 1;
  b[1] = 1;
  ksm(p);
  for (i = 100; i >= 1; i--) {
    if (i == 1) {
      printf("%d\n", b[i] - 1);
    } else
      printf("%d", b[i]);
  }
}

模意义下大整数乘法

也就是快速乘,思路如下

 

 

 注意:也可以利用双精度浮点数在常数时间内计算大整数乘法。因为

 

 快速乘代码实现

ll mul(ll a,ll b,ll p)
{
    ll ans=0;
    for(;b;b>>=1)
    {
        if(b&1)
            ans=(ans+a)%p;
        a=a*2%p;
    }
    return ans;
}

 

双精度代码实现

ll mul(ll a,ll b,ll p)
{
    a%=p;
    b%=p;
    ll c=(long double)a*b/p;
    ll ans=a*b-c*p;
    if(ans<0)
        ans+=p;
    else if(ans>=p)
        ans-=p;
    return ans;
}

 

Guess you like

Origin www.cnblogs.com/2462478392Lee/p/12359044.html