Matrix Multiplication Learning Summary

Source: Internet
Author: User

The so-called matrix multiplication, is a new technique of learning when testing

Is literally understandable, using the multiplication idea to get the matrix we need

The theoretical basis is that the matrix satisfies the binding law and the distribution rate

UVa 11149

Bare topic, given matrix T, to find the matrix of t^1+......+t^n

We all know that using multiplication we can easily find the matrix of T^i (I=2^K), the time complexity is O (M^3LOGN)

We define a matrix of f (k) =t^1+......+t^ (2^K), which defines G (k) =t^ (2^k)

Not hard to find F (k+1) =f (k) +f (k) *g (k), G (k+1) =g (k) *g (k)

We then decompose N in a way that is like a fast power, and when the K bit is 1 we calculate the contribution of F (k) and add the answer

Time complexity O (M^3LOGN), slightly larger constant

#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include < algorithm>using namespace Std;const int mod=10;int n,k;struct matrix{int a[42][42];void Clear () {memset (a,0,sizeof (A ));} void print () {for (int. i=1;i<=n;++i) {for (int j=1;j<=n;++j) {printf ("%d", a[i][j]), if (j==n) printf ("\ n"); else printf ("");}} printf ("\ n");}} A,b,c,i,ans,base; Matrix operator * (const matrix &a,const matrix &b) {matrix C; C.clear (); for (int i=1;i<=n;++i) {for (int. j=1;j<=n;++j) {for (int k=1;k<=n;++k) {c.a[i][j]=c.a[i][j]+a.a[i][k ]*B.A[K][J];} C.a[i][j]%=mod;}} return C;} Matrix operator + (const matrix &a,const matrix &b) {matrix C; C.clear (); for (int. i=1;i<=n;++i) {for (int j=1;j<=n;++j) {c.a[i][j]=a.a[i][j]+b.a[i][j];if (C.a[i][j]>=mod) C.a[i][j]-=mod;}} return C;} void Solve (int p) {b=a; C=a;ans.clear (); Base=i;while (p) {if (p&1) {ans=ans+b*base;base=base*c;} B=b+b*c; C=c*c;p>>=1;} return;} int main () {while (scanf ("%d%d", &n,&k) ==2) {if (!n) break;for (int i=1;i<=n;++i) {for (int j=1;j<=n;++j) {scanf ("%d", &a.a[i][j]); A.a[i][j]%=mod;}} I.clear (); for (int i=1;i<=n;++i) i.a[i][i]=1; Solve (k); Ans.print ();} return 0;}

5.25 Exam Questions T1

We also ask a^0+......+a^ (n-1)

At the time, my approach was to use geometric series summation and matrix inversion to make a mess.

Actually that topic can also write matrix multiply water past

#include <cstdio> #include <iostream> #include <algorithm> #include <cstdlib> #include < Cstring>using namespace Std;    typedef long LONG Ll;const int mod=1e9+7;int t,n,k;struct matrix{LL a[2][2]; void Clear () {memset (a,0,sizeof (a));}} A,b,c,base,ans,i,ans; Matrix operator * (const matrix &a,const matrix &b) {matrix C;    C.clear (); for (int i=0;i<2;++i) {for (int. j=0;j<2;++j) {for (int k=0;k<2;++k) {c.a[i][j]=c.a[                I][j]+a.a[i][k]*b.a[k][j]%mod;            if (c.a[i][j]>=mod) C.a[i][j]-=mod; }}}return C;} Matrix operator + (const matrix &a,const matrix &b) {matrix C;    C.clear ();            for (int. i=0;i<2;++i) {for (int j=0;j<2;++j) {c.a[i][j]=a.a[i][j]+b.a[i][j];        if (c.a[i][j]>=mod) C.a[i][j]-=mod; }}return C;} void Solve (int p) {b=a;    C=a;base=i;ans=i;            while (p) {if (p&1) {ans=ans+b*base;        Base=base*c; }        B=b+b*c;    c=c*c;p>>=1; }return;}    Matrix Pow_mod (Matrix V,int p) {matrix tmp=i;        while (p) {if (p&1) tmp=tmp*v;    v=v*v;p>>=1; }return tmp;}    int main () {scanf ("%d", &t);    A.a[1][0]=a.a[0][1]=a.a[1][1]=1;    I.a[0][0]=i.a[1][1]=1;        while (t--) {scanf ("%d%d", &n,&k);        if (n==1) {printf ("1\n"); continue;} n--;        Solve (n);        Ans=pow_mod (ANS,K); Ans.clear ();        Ans.a[0][1]=1;        Ans=ans*ans;    printf ("%lld\n", ans.a[0][1]); }return 0;}

Bzoj Jiejie's female friend

This topic in Bzoj double experience Qaq, there is also a graph.

First we write out a n*k matrix, and then we write in the k*n matrix.

A lump in the title is obviously a linear combination of a bunch of vectors, so a matrix description can be used to get

Adjacency Matrix G=out*in, then the matrix of the number of paths that happen to be D is g^d

That is (out*in) ^d, we find that out*in gets the matrix of n*n, and In*out gets the matrix of k*k.

N<=1000,k<=20, so using the binding law, we can Bashi out* (in*out) ^ (d-1) *in

And then because the sum of requirements <=d, define T=in*out

out* (t^1+t^2+......+t^ (d-1)) can be obtained according to the distribution rate *in

The middle part uses the matrix multiplication to be able, finally pay attention to judge U==v

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include < Cstdlib>using namespace Std; typedef long LONG Ll;const int mod=1e9+7;int n,m,k,u,v,d; LL out[1010][22],in[22][1010];    ll Tmp[1010][22];struct matrix{ll a[22][22]; void Clear () {memset (a,0,sizeof (a));}} A,b,c,i,base,ans;    void Read (LL &num) {Num=0;char Ch=getchar (); while (ch< '! ')    Ch=getchar ();    while (ch>= ' 0 ' &&ch<= ' 9 ') num=num*10+ch-' 0 ', Ch=getchar (); Num%=mod;} Matrix operator * (const matrix &a,const matrix &b) {matrix C;    C.clear (); for (int i=1;i<=k;++i) {for (int. j=1;j<=k;++j) {for (int k=1;k<=k;++k) {c.a[i][j]=c                . A[i][j]+a.a[i][k]*b.a[k][j]%mod;            if (c.a[i][j]>=mod) C.a[i][j]-=mod; }}}return C;} Matrix operator + (const matrix &a,const matrix &b) {matrix C;    C.clear (); for (int i=1;i<=k;++i) {for (int j=1;j<=k;++j) {c.a[i][j]=a.A[I][J]+B.A[I][J];        if (c.a[i][j]>=mod) C.a[i][j]-=mod; }}return C;} void Get_ans (int p) {b=a;    C=a;ans=i;base=i;            while (p) {if (p&1) {ans=ans+b*base;        Base=base*c;        } b=b+b*c;    c=c*c;p>>=1; }return;}    int main () {scanf ("%d%d", &n,&k);        for (int i=1;i<=n;++i) {for (int j=1;j<=k;++j) read (out[i][j]);    for (int j=1;j<=k;++j) read (In[j][i]); } for (int i=1;i<=k;++i) {for (int. j=1;j<=k;++j) {for (int k=1;k<=n;++k) {A.a[i]                [J]=a.a[i][j]+in[i][k]*out[k][j]%mod;            if (a.a[i][j]>=mod) A.a[i][j]-=mod;    }}} for (int i=1;i<=k;++i) i.a[i][i]=1;    scanf ("%d", &m);        while (m--) {scanf ("%d%d%d", &u,&v,&d);        if (d==0) {printf ("%d\n", (u==v?1:0)); continue;} d--;        Get_ans (d);          for (int i=1;i<=n;++i) {for (int j=1;j<=k;++j) {tmp[i][j]=0;      for (int k=1;k<=k;++k) {tmp[i][j]=tmp[i][j]+out[i][k]*ans.a[k][j]%mod;                if (tmp[i][j]>=mod) Tmp[i][j]-=mod;        }}} LL s=0;            for (int i=1;i<=k;++i) {s=s+tmp[u][i]*in[i][v]%mod;        if (s>=mod) S-=mod;        } if (u==v) s++;        if (s>=mod) S-=mod;    printf ("%lld\n", S); }return 0;}

Bzoj Path in Forest

The title translates to Sigma (i^2*t^i).

First of all, if there is no i^2 we will do, we may as well first consider the i*t^i situation

Define a (i) =t^i,b (i) =i*t^i

Not hard to find B (i) = (i-j) *t^i+j*t^i = ((i-j) *t^ (i-j) *t^j) + (j*t^j*t^ (i-j))

That is, b (i) = B (I-j) *a (j) + B (j) *a (I-J)

So we define C (i) =i^2*t^i

The same reasoning can be obtained

C (i) = C (i-j) *a (j) + C (j) *a (I-j) +2*b (j) *b (I-J)

And we're asking Sigma to do it with a matrix multiplier.

Accidentally wrote Ik*kj ij*jk for one hours Qaq

#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include < Algorithm>using namespace Std;    typedef long LONG ll;int n,m,k,q,u,v;const int mod=1e9+7;struct matrix{LL a[110][110];    LL b[110][110];    LL c[110][110];        void Clear () {memset (a,0,sizeof (a));        Memset (b,0,sizeof (b));    Memset (C,0,sizeof (c)); } void Print () {for (int. i=1;i<=n;++i) {for (int j=1;j<=n;++j) {printf ("%lld", a[i            ][J]);        }printf ("\ n");        }printf ("\ n");            for (int i=1;i<=n;++i) {for (int j=1;j<=n;++j) {printf ("%lld", B[i][j]);        }printf ("\ n");        }printf ("\ n");            for (int i=1;i<=n;++i) {for (int j=1;j<=n;++j) {printf ("%lld", C[i][j]);        }printf ("\ n");    }printf ("\ n"); }}g,a,b,ans,base; Matrix operator * (const matrix &a,const matrix &b) {matrix C;    C.clear (); for (int i=1;i<=n;++i) {for (int j=1;j<=n;++j) {for (int k=1;k<=n;++k) {c.a[i][j]=c.a[i][j]+a.c[i][k]*b.a[                K][J]+A.A[I][K]*B.C[K][J]+2LL*A.B[I][K]*B.B[K][J];                C.a[i][j]%=mod;                C.B[I][J]=C.B[I][J]+A.C[I][K]*B.B[K][J]+A.B[I][K]*B.C[K][J];                C.b[i][j]%=mod;                C.C[I][J]=C.C[I][J]+A.C[I][K]*B.C[K][J];            C.c[i][j]%=mod; }}}return C;} Matrix operator + (const matrix &a,const matrix &b) {matrix C;    C.clear ();            for (int. i=1;i<=n;++i) {for (int j=1;j<=n;++j) {c.c[i][j]=a.c[i][j]+b.c[i][j];            if (c.c[i][j]>=mod) C.c[i][j]-=mod;            C.B[I][J]=A.B[I][J]+B.B[I][J];            if (c.b[i][j]>=mod) C.b[i][j]-=mod;            C.A[I][J]=A.A[I][J]+B.A[I][J];        if (c.a[i][j]>=mod) C.a[i][j]-=mod; }}return C;}    void Solve (int p) {for (int i=1;i<=n;++i) ans.c[i][i]=1;    for (int i=1;i<=n;++i) base.c[i][i]=1; a=g;    b=g; while (p) {        if (p&1) {ans=ans+a*base;        Base=base*b;        } a=a+a*b;    b=b*b;p>>=1; } return;    int main () {scanf ("%d%d%d%d", &n,&m,&k,&q);        for (int i=1;i<=m;++i) {scanf ("%d%d", &u,&v);        g.a[u][v]++;        g.b[u][v]++;    g.c[u][v]++;    } Solve (k);        while (q--) {scanf ("%d%d", &u,&v);    printf ("%d\n", Ans.a[u][v]); } return 0;}

Bzoj 4386

Because Benquan only three-way, so you can make each point into 3 points, so that the edge is 1, the practice with Scoi lost similar

After we consider the two-point answer, we can use matrix multiplication to determine if there are K

So Time complexity O ((3*n) ^3log^2k) will obviously t

First of all, for the convenience of statistics, we can use virtual nodes to connect to each point, and then this virtual point with a self-loop

So because of the existence of the self-ring we do not need to multiply the matrix, the direct rapid power can be

It's not hard to find that we've done some repetitive work every two minutes, and we can consider using multiplication

Preprocess out g^ (2^k), and then try adding from large to small to see if the number of scenarios is >=k

So the time complexity is less than a log

Notice that a long long may be blown out during matrix multiplication.

But we only need to compare with the size of K can be, explode long long is obviously larger than K, so with 1 to indicate this situation can be

Forget to write 1ll<<l result T's Nest at a loss

Notice that the upper bound of the answer is 3*k, and the limit is that the two points have a length of 3 on each side.

#include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> #include < Algorithm>using namespace Std; typedef long Long Ll;int n,m,u,v,w,n,l;    ll K,ans;int idx[42][3];int deg[122];struct matrix{LL a[122][122]; void Clear () {memset (a,0,sizeof (a));}}    G,c,b,a[72];void read (int &num) {Num=0;char Ch=getchar (); while (ch< '! ')    Ch=getchar (); while (ch>= ' 0 ' &&ch<= ' 9 ') num=num*10+ch-' 0 ', Ch=getchar ();} Matrix operator * (const matrix &a,const matrix &b) {matrix C;    C.clear (); for (int i=0;i<=n;++i) {for (int. j=0;j<=n;++j) {for (int k=0;k<=n;++k) {if (a.a[i][k ]==-1| |                B.a[k][j]==-1) {c.a[i][j]=-1;break;} if (a.a[i][k]==0| |                b.a[k][j]==0) continue;                if (A.a[i][k]>k/b.a[k][j]) {c.a[i][j]=-1;break;}                C.A[I][J]+=A.A[I][K]*B.A[K][J];             if (c.a[i][j]>k) {c.a[i][j]=-1;break;} }}}return C;}    BOOL Judge () {LL tot=0; FoR (int i=0;i<=n;++i) {if (!deg[i]) continue;        if (b.a[0][i]==-1) return false;        if (B.a[0][i]>k/deg[i]) return false;        Tot+=b.a[0][i]*deg[i];    if (tot>=k) return false; }return true;}    int main () {read (n); read (m); scanf ("%lld", &k);    for (int i=1;i<=n;++i) {for (int j=0;j<3;++j) idx[i][j]=++n;            } for (int i=1;i<=n;++i) {for (int j=1;j<3;++j) {u=idx[i][j-1];v=idx[i][j];        g.a[u][v]++;    }g.a[0][idx[i][0]]++;    }g.a[0][0]++;        for (int i=1;i<=m;++i) {read (u); Read (v); Read (w);--w;        g.a[idx[u][w]][idx[v][0]]++;    deg[idx[u][w]]++; } for (l=0; (1ll<<l) <=K*3;    l++);    A[0]=g;ans=1;    for (int i=1;i<l;++i) a[i]=a[i-1]*a[i-1];    for (int i=0;i<=n;++i) c.a[i][i]=1;        for (int i=l-1;i>=0;--i) {b=c*a[i];            if (judge ()) {c=b;        ans+= (1ll<<i);    }} if (ans>k*3) printf (" -1\n");    else printf ("%lld\n", ans); return 0;}

Multiplication is a kind of thought, using any natural number can be written into Logn binary

If each contribution to the answer can be calculated independently, then we multiply the pre-processing of each bit and then merge it.

It can also be used for the conversion of two points, and to find a way of K-size

Common multiplication has a fast power, lca,rmq, matrix multiplication, etc.

The complexity of time is log.

Matrix Multiplication Learning Summary

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.