头像

欢迎来到我的博客

分享题解与总结

R - Walk

最近 离散小波老师 讲了矩阵快速幂和矩阵乘法

我暂时写不出 美食家 那题

先做了几道相关的题

Atcoder dp contest R - Walk

R - Walk

题目:

求出 满足从 \(i\)\(j\) 经过 \(k\) 条边的路径条数

思路:

单纯的邻接矩阵乘法

\(A_{i,j}^1\):表示\(i → j\),只经过 1 条边的方案数

\(A_{i,j}^2\):表示\(i → j\),只经过 2 条边的方案数

(拆开来看:\(A_{2,3}^1=5,A_{3,6}^1=2 \Rightarrow A_{2,6}^2 +=10\))

... ...

\(A_{i,j}^k\):表示\(i → j\),只经过 k 条边的方案数

其中,

\[A_{i,j}^1= \begin{cases} 0, e[i][j]=0 \\ 1, e[i][j]=1 \\ \end{cases} \]

代码:

const int MOD=1e9+7;

struct Matrix{
    vector<vector<ll>> a;
    Matrix(int n){
        a.resize(n);
        for(int i=0;i<n;++i) a[i].resize(n,0);
    }
};

Matrix operator*(const Matrix& A,const Matrix& B)
{
    int n=A.a.size();
    Matrix C(n);
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j){
            for(int k=0;k<n;++k){
                C.a[i][j]=((C.a[i][j]+A.a[i][k]*B.a[k][j])%MOD+MOD)%MOD;
            }
        }
    }
    return C;
}

struct Vec{
    vector<ll> a;
    Vec(int n){
        a.resize(n,0);
    }
};

Vec operator*(const Matrix& A,const Vec& B){
    int n=A.a.size();
    Vec C(n);
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j){
            C.a[i]=((C.a[i]+A.a[i][j]*B.a[j])%MOD+MOD)%MOD;
        }
    }
    return C;
}

Matrix qpow(Matrix A,ll k)
{
    int n=A.a.size();
    Matrix ans(n);
    for(int i=0;i<n;++i) ans.a[i][i]=1;//!!!
    while(k){
        if(k&1) ans=ans*A;
        A=A*A;
        k>>=1;
    }
    return ans;
}

int main()
{
    int n;ll k;
    cin>>n>>k;
    Matrix A(n);
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j){
            cin>>A.a[i][j];
        }
    }
    A=qpow(A,k);
    ll ans=0;
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j){
            ans=((ans+A.a[i][j])%MOD+MOD)%MOD;
        }
    }
    cout<<ans;
    return 0;
}

注意:

这里的\(C\)矩阵,实际上就是\(C=A \times A\)

\(C_{i,j}= \sum_{k=1}^n A_{i,k} \times A_{k,j}\) ,即\(C_{i,j} += A_{i,k} \times A_{k,j}\)

其中每一次计算\(A_{i,k} \times A_{k,j}\),都是相当于是:\(i \rightarrow k \rightarrow j\)是一种方案,统计该方案对\(C_{i,j}\)的贡献

Matrix operator*(const Matrix& A,const Matrix& B)
{
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j){
            for(int k=0;k<n;++k){
                C.a[i][j]+=A.a[i][k]*B.a[k][j];
            }
        }
    }
    return C;
}
posted @ 2026-08-27 20:27  king_steph1209  阅读(5)  评论(0)    收藏  举报