DP Optimization: matrix multiplication

## ~ ~ saying this is the first blog blogger. . .
### Ahem cough, talking about today is a DP optimization strategies - matrix multiplication
on the optimization of matrix multiplication DP subject can be used, has the following requirements:

1. Only the adder transfer type, clears, subtraction etc., max and min is not allowed in
2. The transfer type on the first few coefficients dp result must be a constant
3. Usually the number of transitions Super Multi
4. Since the number of times of transfer and generally have a modulus number within the range int

In summary, an example:

> $dp[ i ]=a×dp[ i-1 ]+b×dp[ i-2]+c×dp[ i-3 ]$

Wherein, a, b, c are constants, and the required matrix optimization of the DP, often i 2 ^ 128 or the like, particularly Kichiku particularly large number;
because the optimized matrix multiplication find DP [i] is in O time log (i) is completed.
So, how to achieve matrix multiplication, its principle is Shane?
Matrix multiplication requires two matrices A and B, A is an n × p, B is the size of p × m, below! [This figure is taken from Baidu Encyclopedia] (https://img-blog.csdnimg.cn/20190504223656773. jpg)
for ease of explanation, we give examples of Fibonacci deed.
Fibonacci transfer formula is: dp [i] = dp [ i-1] + dp [i-2].
We then (dp [i], dp [ i-1]) regarded as a 1 × 2 matrix A is
each time multiplied by the matrix A is equivalent to transfer F.:
|. 1. 1 |
| 0. 1 |
the results is: $ (dp [i] + dp [i-1], dp [i]) $, i.e. $ (dp [i + 1] , dp [i]) $
then once every 8 matrix multiplication requires operation, while the original state transition required only once, so do not see matrix multiplication algorithm on a waste wood it. .
The key is! Matrix multiplication is associative ** has **, hey hey hey, then we can start ** ** fast power up! Look at it this way O (n) algorithm optimization has become a simple O (8 × logn) algorithm in ** n ** Fried Chicken Fried Chicken big metamorphosis time we can use this optimized.
[Fibonacci original title] (https://www.luogu.org/problemnew/show/P1962)
Code:

```cpp
#include<bits/stdc++.h>
using namespace std;
long long n;
const int MOD=1e9+7;
void mul(int f[2],int a[2][2]){
int c[2];
memset(c,0,sizeof(c));
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c[j]=(c[j]+(long long)f[k]*a[k][j])%MOD;
memcpy(f,c,sizeof(c));
}
void mulself(int a[2][2]){
int c[2][2];
memset(c,0,sizeof(c));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c[i][j]=(c[i][j]+(long long)a[i][k]*a[k][j])%MOD;
memcpy(a,c,sizeof(c));
}
int main(){
scanf("%lld",&n);
int f[2]={0,1};
int a[2][2]={{0,1},{1,1}};
for (; n-; n->> =. 1) {
IF (n-&. 1) MUL (F, A);
mulself (A); 
} the printf ( "% D \ n-", F [0]);
return 0;
}
`` `
Fibonacci second-order matrix multiplication, complexity is $ O $ (2 ^ 3 ^ × logm), (m is the size required to sequence DP) as well as third-order and even order n matrix multiplication, as if the complexity is $ O $ (n ^ 3 ^ × logm), on the third-order example: [third order example] (https://www.luogu.org/problemnew/show/P1939)
third-order words actually put matrix can be opened into 3 × 1 and of the 3 × 3.
Standard process:

```cpp
#include<bits/stdc++.h>
using namespace std;
int T;
int n;
const int mod=1e9+7;
void mul(int f[3],int a[3][3]){
int c[3];
memset(c,0,sizeof(c));
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
c[j]=(c[j]+(long long)f[k]*a[k][j])%mod;
memcpy(f,c,sizeof(c));

void mulself(int a[3][3]){
int c[3][3];
memset(c,0,sizeof(c));
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
c[i][j]=(c[i][j]+(long long)a[i][k]*a[k][j])%mod;
memcpy(a,c,sizeof(c));
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
F int [. 3] = {0,0,1};
int A [. 3] [. 3] = {{1,1,0}, {0,0,1}, {1,0,0}};
for (; n-; n->> =. 1) {
IF (n-&. 1) MUL (F, A);
mulself (A);
}
the printf ( "% D \ n-", F [0]);
}
return 0;

`` `
uh, here to make ad ** **: [bloggers themselves out of the question, n order, almost purple title bar] (https://www.luogu.org/problemnew/show/T77626)
~ ~ talk ~ true super water 
### followed by more classic example:
##### ** ** embodiment a
set of a function F (n), represents a number from 1 to even up all integers n, for example: f (1) = 1, f (6) = 123456, f (11) = 1234567891011. Request f (n) of the modulus value 1e9 + 7
range large: the n-<= 1e18
emmm, look at this question, even if you find mold is not so 1e18 1e9 + 7 Ba most direct output will explode and algorithms on this topic only O (logn) Come QAQ.
So we find that f (n) can be connected by a (n-1) f n obtained later, the obtained 3 × 3 matrix of a transfer impossible calculated:
| log 10 ^ (n-1) 0 ^ 0 |
|. 1 0 1 |
| 0 1 1 |
is multiplied by matrix | f (n), n + 1,1 |
obviously, 10 ^ log (n-1 ) ^ is impossible to work out, then we can do this:
E.g. n-= 999
| 0. 1. 1 | × | 10 0 0 | ^. 9 ^ × | 100 0 0 | ^ 90 ^ × | 1000 0 0 | ^ 899 ^
________ |. 1. 1 0 | ___ |. 1. 1 0 | ______ | 1 0 1 |
________ | 0 1 1 | ___ | 0 1 1 | ______ | 1 1 0 |
solved la la la la (~ ¯ ▽ ¯) ~

Guess you like

Origin www.cnblogs.com/china-xyc/p/11616820.html