• 【矩阵专题】


    http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6930


    1000:

    题意:裸的斐波拉契,裸的不能再裸 n<10^12;


    代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    #define LL long long
    using namespace std;
    struct node
    {
        int mat[2][2];
    };
    node a={1,1,1,0};
    node ret={1,0,0,1};
    node NUL={0,0,0,0};
    node matmult(node A,node B,int mod)
    {
        node C=NUL;
        for(int i=0;i<2;i++)
             for(int j=0;j<2;j++)
               for(int k=0;k<2;k++)
        {
            C.mat[i][j]=(C.mat[i][j]+A.mat[i][k]*B.mat[k][j])%mod;
        }
        return C;
    }
    node quickmatpow(node A,LL n,int mod)
    {
        node c=ret;
        while(n!=0)
        {
            if(n&1==1) c=matmult(c,A,mod);
            n=n>>1;
            A=matmult(A,A,mod);
        }
        return c;
    }
    LL n;
    void init()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    int main()
    {
     //   init();
        node c;
    	while(cin>>n&&n!=-1)
        {
            c=quickmatpow(a,n,10000);
            printf("%d
    ",c.mat[0][1]);
        }
    }
    



    1001

    题意

    A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973。
    裸的 没什么好说的
    /*
    第一次没过样例是因为 写ret 的时候 只给对角线赋值为1 忘记clear了
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    #define LL long long
    using namespace std;
    void init()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    struct node
    {
        int mat[15][15];
        void clear()
        {
            for(int i=0;i<15;i++)
                 for(int j=0;j<15;j++)
                 mat[i][j]=0;
        }
        void ret()
        {
              for(int i=0;i<15;i++)
                 for(int j=0;j<15;j++)
                 mat[i][j]=0;
            for(int i=0;i<15;i++)
                mat[i][i]=1;
        }
    };
    node fir;
    LL n,k;
    node matmult(node a,node b,int mod)
    {
        node c;
        c.clear();
        for(int i=0;i<n;i++)
          for(int j=0;j<n;j++)
             for(int k=0;k<n;k++)
               c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
        return c;
    }
    node quickmatpow(node a,LL n,int mod)
    {
        node c;
        c.ret();
        while(n!=0)
        {
            if(n&1==1)  c=matmult(c,a,mod);
            n=n>>1;
            a=matmult(a,a,mod);
        }
        return c;
    }
    void input()
    {
        scanf("%I64d%I64d",&n,&k);
        for(int i=0;i<n;i++)
          for(int j=0;j<n;j++)
           scanf("%d",&fir.mat[i][j]);
    }
    void solve()
    {
       node c;
       int ans=0;
       c=quickmatpow(fir,k,9973);
       for(int i=0;i<n;i++)
       {
           ans=(ans+c.mat[i][i])%9973;
       }
       printf("%d
    ",ans);
    }
    int main()
    {
       // init();
    	int T;
    	cin>>T;
    	while(T--)
        {
            input();
            solve();
        }
        return 0;
    }
    



    1002

    题意:

    A是一个矩阵 计算S=A+A^2......A^k-1+A^k;


    区分奇偶来二分! 看了题解才会做的

    本来的想法是涉及到矩阵的逆的

    /*
    1.WA  不明原因 改成全long long
    
    2.
    
    2 1000000 4
    0 1
    1 1
    99%错误答案:
    0 0
    0 0
    
    调试原因:不清楚
    3.WA 继续调试2
    4.发现原因 n为奇数时处理错误
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    #define LL long long
    using namespace std;
    struct node
    {
        LL mat[40][40];
        void clear()
        {
            for(int i=0;i<40;i++)
                for(int j=0;j<40;j++)
                mat[i][j]=0;
        }
        void ret()
        {
            clear();
            for(int i=0;i<40;i++)
                mat[i][i]=1;
        }
    };
    LL n,k,m;
    node A;
    void init()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    void input()
    {
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            scanf("%I64d",&A.mat[i][j]);
    }
    node matmult(node a,node b,LL mod)
    {
        node c;
        c.clear();
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                for(int k=0;k<n;k++)
                c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
        return c;
    }
    node quickmatpow(node a,LL n,LL mod)
    {
        node c;
        c.ret();
        while(n!=0)
        {
            if(n&1==1) c=matmult(c,a,mod);
            n=n>>1;
            a=matmult(a,a,mod);
        }
        return c;
    }
    node matadd(node a,node b,LL mod)
    {
      node c;
      for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        c.mat[i][j]=(a.mat[i][j]+b.mat[i][j])%mod;
        return c;
    }
    node getans(int n,int mod)
    {
        node c,d;
        c.clear();
        d.clear();
        if(n==1) return A;
        else
        {
            c=getans(n/2,mod);
            if(n%2==0)
            {
                d=quickmatpow(A,n/2,mod);
                return matadd(c,matmult(d,c,mod),mod);
            }
            else
            {
                d=quickmatpow(A,(n/2)+1,mod);
                return matadd(d,matadd(c,matmult(d,c,mod),mod),mod);
            }
        }
    }
    void solve()
    {
        node ans;
        ans.clear();
        ans=getans(k,m);
        for(int i=0;i<n;i++)
          {
           for(int j=0;j<n;j++)
            {
                printf("%I64d",ans.mat[i][j]);
                if(j!=n-1) printf(" ");
            }
            printf("
    ");
          }
    }
    int main()
    {
        //init();
        while(cin>>n>>k>>m)
        {
            input();
            solve();
        }
    }


    1003

    题意:

    询问长度为N的队伍中 可能为M,或F 问不存在 FFF或FMF的排列总数。

    之前做过的一道题

    http://blog.csdn.net/zy691357966/article/details/43084647

    #include <cstdio>  
    #include <cstdlib>  
    #include <cmath>  
    #include <cstring>  
    #include <ctime>  
    #include <algorithm>  
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313   
    using namespace std;
    int L,M;
    struct node
    {
        int mat[5][5];
    }a,e,ans;
    int mat2[5];
    void CSH()
    {
        mat2[1]=9;
        mat2[2]=6;
        mat2[3]=4;
        mat2[4]=2;
        for(int i=1;i<=4;i++)
    {
            e.mat[i][i]=1;
            mat2[i]=mat2[i]%M;
    }
        memset(a.mat,0,sizeof(a.mat));
        a.mat[1][1]=a.mat[1][3]=a.mat[1][4]=1;
        a.mat[2][1]=a.mat[3][2]=a.mat[4][3]=1;
    }
    node MatrixMult(node A,node B,int mod)
    {
        node p;
        memset(p.mat,0,sizeof(p.mat));
        for(int i=1;i<=4;i++)
         for(int j=1;j<=4;j++)
         {
              for(int k=1;k<=4;k++)
             p.mat[i][j]+=A.mat[i][k]*B.mat[k][j];
             p.mat[i][j]=p.mat[i][j]%mod;
         }
         return p;
    }
    node kuaisumi(node A,int N,int mod)
    {
        node di=e;
        while(N>0)
        {
            if(N&1)
            {
                di=MatrixMult(di,A,mod);
            }
            A=MatrixMult(A,A,mod);
            N=N>>1;
        }
        return di;
    }
    void solve()
    {
        int ANS=0;
        for(int i=1;i<=4;i++)
        {
            ANS+=ans.mat[1][i]*mat2[i];
            ANS=ANS%M;
        }
        printf("%d
    ",ANS);
    }
    int main()
    {
        while(cin>>L>>M)
        {
            CSH();
            if(L>4)
            ans=kuaisumi(a,L-4,M);
            if(L>4)
            solve();
            else 
            printf("%d
    ",mat2[L]);
        }
        return 0;
    }
    


    1004

    题目大意:
    If x < 10 f(x) = x.
    If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
    And ai(0<=i<=9) can only be 0 or 1 .


    齐次递推,很容易由1003 得出公式

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define LL long long
    #define oo 0x13131313
    using namespace std;
    LL k,m;
    void init()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    struct node
    {
        LL mat[15][15];
        void clear() {memset(mat,0,sizeof(mat));}
        void ret()   {
                        clear();
                        for(int i=0;i<15;i++)
                            mat[i][i]=1;
                     }
    };
    node A;
    void input()
    {
        A.clear();
        for(int i=0;i<10;i++)
        scanf("%d",&A.mat[0][i]);
        for(int i=1;i<10;i++)
        A.mat[i][i-1]=1;
    }
    node matmult(node a,node b,LL mod)
    {
        node c;c.clear();
        for(int i=0;i<10;i++)
            for(int j=0;j<10;j++)
              for(int k=0;k<10;k++)
               c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
        return c;
    }
    node quickmatpow(node a,LL n,LL mod)
    {
        node c;c.ret();
        while(n!=0)
        {
            if(n&1==1) c=matmult(c,a,mod);
            n=n>>1;
            a=matmult(a,a,mod);
        }
        return c;
    }
    void solve()
    {
        LL ans=0;
        node c;c.clear();
        c=quickmatpow(A,k-9,m);
        for(int i=0;i<10;i++)
        ans=(ans+c.mat[0][i]*(9-i))%m;
        printf("%I64d
    ",ans);
    }
    int main()
    {
       // init();
    	while(cin>>k>>m)
        {
            input();
            solve();
        }
        return 0;
    }
    


    接下来几个题目太强悍了 我必须新写一篇

  • 相关阅读:
    封装的图片预加载,数据加载到浏览器底部加载数据
    自己封装的弹出层插件
    在规定的时间内出现动画.html
    WEB前端资源集
    前端优化几项
    移动H5前端性能优化指南
    微信小程序IDE(微信web开发者工具)安装、破解手册--转载
    微信小程序开发—快速掌握组件及API的方法---转载
    STM32数据类型定义
    HDOJ 4802 GPA
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480392.html
Copyright © 2020-2023  润新知