• 矩阵模板hdu5015,UVA 10655,UVA 11149


    hdu5015

    n是<=10的,可以想到点什么,,
    构造矩阵mat[n+2][n+2]
    这里写图片描述
    发现mat*a是答案矩阵第1列
    mat的m次方再乘a就是答案矩阵的第m列,取最下面的就行了

    这板不错

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    const int P = 10000007;
    const int N=13;
    ll n,m;
    
    struct matrix{
        ll a[N][N];
        int row,col;
        matrix():row(N),col(N){
            memset(a,0,sizeof(a));
        }
        matrix(int x,int y):row(x),col(y){
            memset(a,0,sizeof(a));
        }
        ll* operator [] (int x){
            return a[x];
        }
        matrix operator * (matrix x){
            matrix tmp ;
            for (int i=0;i<=n+1;i++)
                for (int j=0;j<=n+1;j++){
                    tmp[i][j]=0;
                    for (int k=0;k<=n+1;k++)
                        tmp[i][j]=(tmp[i][j]+a[i][k]*x[k][j])%P;
                }
            return tmp;
        }   
        void operator *= (matrix x){
            *this = *this * x;
        }
        matrix operator ^ (ll x){
            matrix ret;
            for (int i=0;i<=n+1;i++)ret[i][i]=1;
            matrix tmp = *this;
            for (;x;x>>=1,tmp*=tmp){if(x&1)ret *=tmp;}
            return ret;
        }
        void print(){
            for (int i=0;i<=n+1;i++){
                for (int j=0;j<=n+1;j++)
                    printf("%d ",a[i][j]);
                puts("");
            }
        }
    };
    
    matrix getMatrix(){
        matrix mat;
        mat[0][0]=10;
        mat[0][n+1]=1;
        for (int i=1;i<=n;i++)
            for (int j=0;j<=i;j++)mat[i][j]=1;
        for (int i=0;i<=n;i++)mat[n+1][i]=0;
        mat[n+1][n+1]=1;
        return mat;
    }
    
    int main(){
        //freopen("fuck.in","r",stdin);
        while (~scanf("%I64d%I64d",&n,&m)){
            matrix a;
            for (int i=1;i<=n;i++)scanf("%I64d",&a[i][0]);
            a[0][0] = 233,a[n+1][0] = 3;
            matrix mat = getMatrix();
            mat = (mat ^ m) * a;
            printf("%I64d
    ",mat[n][0]%P);
        }
        return 0;
    } 

    UVA 10655
    题解
    题目大意:给出a+b的值和ab的值,求a^n+b^n的值。

    题目分析:有种错误的方法是这样的:利用已知的两个方程联立,求解出a和b,进而求出答案。这种方法之所以错,是因为这种方法有局限性。联立之后会得到一个二元一次方程,只有当该方程有实数解确切的说是当某个数据满足该方程有实数解时,这种方法得到的结果才有可能正确。显然,题中数据不可能这么片面。正确的方法是这样的:

    令a+b=A,ab=B,S(n)=an+bn。
    则S(n)=an+bn=(a+b)(a^n-1+b^n-1)-a*b^n-1-a^n-1*b
    =(a+b)(an-1+bn-1)-ab(an-2+bn-2)=A*S(n-1)-B*S(n-2)  (n≥2)。
                          
    由此构造2x2的矩阵:
    matrix[1][1]=A,matrix[1][2]=-B;
    matrix[2][1]=1,matrix[2][2]=0;

    n=1或n=0时,答案显然。

    要注意:数据中可能会出现A=B=0的情况,此时a=b=0,所以不能简单的判定当A=B=0时就结束输入数据。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    const int N=4;
    
    struct matrix{
        ll a[N][N];
        int row,col;
        matrix():row(N),col(N){
            memset(a,0,sizeof(a));
        }
        matrix(int x,int y):row(x),col(y){
            memset(a,0,sizeof(a));
        }
        ll* operator [] (int x){
            return a[x];
        }
        matrix operator * (matrix x){
            matrix tmp ;
            for (int i=1;i<=2;i++)
                for (int j=1;j<=2;j++){
                    tmp[i][j]=0;
                    for (int k=1;k<=2;k++)
                        tmp[i][j]=(tmp[i][j]+a[i][k]*x[k][j]);
                }
            return tmp;
        }
        void operator *= (matrix x){
            *this = *this * x;
        }
        matrix operator ^ (ll x){
            matrix ret;
            for (int i=1;i<=2;i++)ret[i][i]=1;
            matrix tmp = *this;
            for (;x;x>>=1,tmp*=tmp){if(x&1)ret *=tmp;}
            return ret;
        }
        void operator ^=(ll x){
            *this = *this ^ x;
        }
        void print(){
            for (int i=1;i<=2;i++){
                for (int j=1;j<=2;j++)
                    printf("%d ",a[i][j]);
                puts("");
            }
        }
    };
    
    ll solve(ll a ,ll b ,ll n){
        if (n==0) return 2;
        if (n==1) return a;
        if (a==0&&b==0)return 0;
        matrix tra,ans;
        tra[1][1]=a;tra[1][2]=-b;
        tra[2][1]=1;tra[2][2]=0;
        ans[1][1]=a;
        ans[2][1]=2;
        ans = (tra^n)*ans;
        return ans[2][1];
    }
    
    int main(){
        //freopen("fuck.in","r",stdin);
        ll p,q,n;
        while (scanf("%lld%lld%lld",&p,&q,&n)==3){
            printf("%lld
    ",solve(p,q,n));
        }
        return 0;
    }

    UVA 11149
    题解
    题目大意:给一个n阶方阵,求A1+A2+A3+……Ak。

    题目分析:令F(k)=A1+A2+A3+……Ak。当k为偶数时,F(k)=F(k/2)(E+Ak/2),k为奇数时,F(k)=F(k/2)(E+Ak/2)+Ak。证明这两条公式也很简单,把这两条公式展开就行了。根据公式,递归即可。

    /*
     * UVA 11149    Power of Matrix
     * by cww97
    */
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    const int N=43;
    int n;
    
    struct matrix{
        ll a[N][N];
        int row,col;
        matrix():row(N),col(N){
            memset(a,0,sizeof(a));
        }
        matrix(int x,int y):row(x),col(y){
            memset(a,0,sizeof(a));
        }
        ll* operator [] (int x){
            return a[x];
        }
        matrix operator + (matrix x){
            matrix tmp ;
            for (int i=1;i<=n;i++)
                for (int j=1;j<=n;j++){
                    tmp[i][j]=(a[i][j]+x[i][j])%10;
                }
            return tmp;
        }
        void operator += (matrix x){
            *this = *this + x;
        }
        matrix operator * (matrix x){
            matrix tmp ;
            for (int i=1;i<=n;i++)
                for (int j=1;j<=n;j++){
                    tmp[i][j]=0;
                    for (int k=1;k<=n;k++)
                        tmp[i][j]=(tmp[i][j]+a[i][k]*x[k][j])%10;
                }
            return tmp;
        }
        void operator *= (matrix x){
            *this = *this * x;
        }
        matrix operator ^ (ll x){
            matrix ret;
            for (int i=1;i<=n;i++)ret[i][i]=1;
            matrix tmp = *this;
            for (;x;x>>=1,tmp*=tmp){if(x&1)ret *=tmp;}
            return ret;
        }
        void operator ^=(ll x){
            *this = *this ^ x;
        }
        void print(){
            for (int i=1;i<=n;i++){
                for (int j=1;j<n;j++)
                    printf("%d ",a[i][j]%10);
                printf("%d
    ",a[i][n]%10);
            }
            puts("");
        }
    }E,A;
    
    matrix f(int k){
        if (k==1)return A;
        matrix tmp = f(k>>1)*((A^(k>>1)) +E);
        if (k&1)tmp +=(A^k);
        return tmp;
    }
    
    int main(){
        //freopen("fuck.in","r",stdin);
        int k,x;
        while (scanf("%d%d",&n,&k)==2&&n){
            for (int i=1;i<=n;i++){
                for (int j=1;j<=n;j++){
                    scanf("%d",&x);
                    A[i][j]=x%10;
                }
            }
            for (int i=1;i<=n;i++)E[i][i]=1;
            A = f(k);
            A.print();
        }
        return 0;
    }
    
  • 相关阅读:
    01--图解数据结构之数组实现容器
    00--图解数据结构之开篇+容器基类
    O3-开源框架使用之Butterknife 8.8.1及源码浅析
    3-VII-RecyclerView的item操作
    D11-Android自定义控件之动画篇3-插值器与估值器
    D10-Android自定义控件之动画篇2-动画监听
    /var/spool/postfix/maildrop 出现大量文件原因和解决办法
    golang捕获迭代变量,实参的估值时刻
    Golang标准库深入
    golang中type关键字使用
  • 原文地址:https://www.cnblogs.com/cww97/p/7533986.html
Copyright © 2020-2023  润新知