• 矩阵模板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;
    }
    
  • 相关阅读:
    27 Spring Cloud Feign整合Hystrix实现容错处理
    26 Spring Cloud使用Hystrix实现容错处理
    25 Spring Cloud Hystrix缓存与合并请求
    24 Spring Cloud Hystrix资源隔离策略(线程、信号量)
    23 Spring Cloud Hystrix(熔断器)介绍及使用
    22 Spring Cloud Feign的自定义配置及使用
    21 Spring Cloud使用Feign调用服务接口
    20 Spring Cloud Ribbon配置详解
    19 Spring Cloud Ribbon自定义负载均衡策略
    18 Spring Cloud Ribbon负载均衡策略介绍
  • 原文地址:https://www.cnblogs.com/cww97/p/12349393.html
Copyright © 2020-2023  润新知