zoukankan      html  css  js  c++  java
  • HDU4686——Arc of Dream矩阵快速幂

    题目链接

      http://acm.hdu.edu.cn/showproblem.php?pid=4686

    题目大意

      已知a0=A0,  ai=Ax*ai-1+Ay;

        b0=B0,  bi=Bx*bi-1+By;

      求∑ai*bi(i=0-->n-1)。

      n不超过1018,A0,Ax,Ay,B0,Bx,BY不超过2*109

    题目分析

      因为n很大,不可能用递推来做,这个时候就想到了矩阵的方法。构造了好几个满足要求的,但都是仅仅满足ai或者bi的,最后才发现,把ai*bi按递推式展开,

    ai*bi=Ax*By*ai-1*bi-1+Ax*By*ai-1+Ay*Bx*bi-1+By*Ay。将常数组合在一起构成一个矩阵,将变量组合在一起构成另一个矩阵,然后将ai*bi构造成矩阵递推式:

    矩阵1:

      1  ai  bi  ai*bi  si(求和)

      0  0  0      0     0

      0  0  0      0     0

      0  0  0      0     0

      0  0  0      0     0

    矩阵2:

      1  Ay  By  Ay*By  Ay*By

      0  Ax  0    Ax*By  Ax*By

      0  0    Bx  Ay*Bx  Ay*Bx

      0  0    0    Ax*By  Ax*By

      0  0    0    0     1

    矩阵3

      1  ai+1  bi+1  ai+1*bi+1  si(求和)

      0  0  0      0     0

      0  0  0      0     0

      0  0  0      0     0

      0  0  0      0     0

    显然  矩阵1*矩阵2=矩阵3。根据递推关系呢,矩阵1(i=0)*(矩阵2)n-1就能得到s(n-1)了。因而,用矩阵快速幂就能很快把问题解决了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const long long mod=1000000007;
     6 typedef struct
     7 {
     8     long long m[5][5];
     9 }mat;
    10 mat X,Y;
    11 mat multi(mat x,mat y)
    12 {
    13     mat temp;
    14     for(int i=0;i<5;i++)
    15         for(int j=0;j<5;j++)
    16         {
    17             temp.m[i][j]=0;
    18             for(int k=0;k<5;k++)
    19                 temp.m[i][j]+=x.m[i][k]*y.m[k][j]%mod;
    20             temp.m[i][j]%=mod;
    21         }
    22     return temp;
    23 }
    24 
    25 mat pow(long long k)//矩阵快速幂
    26 {
    27     mat ans=X,p=Y;
    28     while(k)
    29     {
    30         if(k&1)
    31             ans=multi(ans,p);
    32         p=multi(p,p);
    33         k/=2;
    34     }
    35     return ans;
    36 }
    37 
    38 int main()
    39 {
    40     long long n,a0,ax,ay,b0,bx,by;
    41     while(cin>>n>>a0>>ax>>ay>>b0>>bx>>by)
    42     {
    43         if(!n)//这边需要注意特判一下
    44         {
    45             printf("0
    ");
    46             continue;
    47         }
    48         memset(X.m,0,sizeof(X.m));
    49         memset(Y.m,0,sizeof(Y.m));
    50         X.m[0][0]=1;X.m[0][1]=a0;X.m[0][2]=b0;X.m[0][3]=a0*b0%mod;X.m[0][4]=a0*b0%mod;
    51         Y.m[0][0]=1;Y.m[0][1]=ay;Y.m[0][2]=by;Y.m[0][3]=ay*by%mod;Y.m[0][4]=ay*by%mod;
    52         Y.m[1][1]=ax;Y.m[1][3]=Y.m[1][4]=ax*by%mod;
    53         Y.m[2][2]=bx;Y.m[2][3]=Y.m[2][4]=ay*bx%mod;
    54         Y.m[3][3]=Y.m[3][4]=ax*bx%mod;
    55         Y.m[4][4]=1;
    56         mat ans=pow(n-1);
    57         long long s=ans.m[0][4]%mod;
    58         cout<<s<<endl;
    59     }
    60     return 0;
    61 }
    HDU4686

      

  • 相关阅读:
    一、介绍与基础操作命令
    ES配置详细说明
    通过命令名称查询进程id
    应用商店流程
    你对女人好并不会让她爱上你
    java 对list进行排序
    java web判断是否登录
    支付返回post请求数据
    不方便的事情,人们都不大会去做
    不方便的事情,人们都不大会去做
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/HDU4686-ArcofDream.html
Copyright © 2011-2022 走看看