• hdu 1588 又是矩阵


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1588

    比hdu 1757难了好多,看了好多别人的博客才明白。。。哎。。。

    View Code
     1 /*
     2 *题意:g(i)=k*i+b,sum(f(g(i)) for 0<=i<n
     3 *根据Fibonacci矩阵的求法,f(i)=mat^i 令mat={1,1,1,0}(二阶矩阵)
     4 *f(g(i))=mat^g(i)=mat^(ki+b)
     5 *sum(f(g(i))=mat^b+mat^(k+b)+...+mat^(ki+b) for 0<=i<n
     6 *提取mat^b得:sum(f(g(i))=mat^b+mat^b[mat^(k)+mat^2k...+mat^(ki)]
     7 *问题转化为求 mat^(k)+mat^2k...+mat^(ki)
     8 *对等比矩阵进行二分求和,做法如下:
     9 *求得matk=mat^k
    10 *原式=matk+matk^2+...+matk^i
    11 *如果 i 为偶数:原式=(matk+matk^2+...+matk^i/2)+matk^(i/2)(matk+matk^2+...+matk^i/2)
    12 *如果(i)为奇数:那我们干脆先计算前面的i-1个偶数
    13 * 用前面所诉的方法 tmp1=matk+matk^2+...+matk^i/2 tmp2=tmp1*matk^i/2
    14 * 前偶数个的和tmp=tmp1+tmp2
    15 * 最后的结果=tmp+matk^i
    16 */
    17 
    18 
    19 #include<iostream>
    20 using namespace std;
    21 
    22 int k,b,n,m;
    23 struct Matrix {
    24     __int64 map[2][2];
    25 };
    26 Matrix matrix,matk,matb,smat;
    27 
    28 //矩阵乘法
    29 Matrix Mul(Matrix &a,Matrix &b){
    30     Matrix c;
    31     for(int i=0;i<2;i++){
    32         for(int j=0;j<2;j++){
    33             c.map[i][j]=0;
    34             for(int k=0;k<2;k++){
    35                 c.map[i][j]+=a.map[i][k]*b.map[k][j];
    36                 c.map[i][j]%=m;
    37             }
    38         }
    39     }
    40     return c;
    41 }
    42 
    43 //快速幂
    44 Matrix Pow(int k,Matrix &temp){
    45     if(k==1)return temp;
    46     else if(k&1){
    47         return Mul(temp,Pow(k-1,temp));
    48     }else {
    49         Matrix tmp=Pow(k>>1,temp);
    50         return Mul(tmp,tmp);
    51     }
    52 }
    53 
    54 //矩阵加法
    55 Matrix Sum(Matrix &a,Matrix &b){
    56     Matrix c;
    57     for(int i=0;i<2;i++){
    58         for(int j=0;j<2;j++){
    59             c.map[i][j]=a.map[i][j]+b.map[i][j];
    60             c.map[i][j]%=m;
    61         }
    62     }
    63     return c;
    64 }
    65 
    66 //等比数列二分求和
    67 Matrix Binary_Sum(int k){
    68     if(k==1)return matk;
    69     else if(k&1){
    70         //奇数时前k-1项与matk^k相加
    71         return Sum(Binary_Sum(k-1),Pow(k,matk));
    72     }else {
    73         Matrix tmp1=Binary_Sum(k>>1);//先算前k/2项
    74         Matrix tmp2=Mul(Pow(k>>1,matk),tmp1);
    75         return Sum(tmp1,tmp2);
    76     }
    77 }
    78 
    79 int main(){
    80     matrix.map[0][0]=1,matrix.map[0][1]=1;
    81     matrix.map[1][0]=1,matrix.map[1][1]=0;
    82     while(scanf("%d%d%d%d",&k,&b,&n,&m)!=EOF){
    83         matk=Pow(k,matrix);//求matrix^k;
    84         smat=Binary_Sum(n-1);//求matk的等比数列的前n-1项和
    85         if(b){
    86             matb=Pow(b,matrix);
    87             smat=Mul(matb,smat);//sum=sum*matb;
    88             smat=Sum(matb,smat);//sum+=matb;
    89         }
    90         printf("%I64d\n",smat.map[1][0]);
    91     }
    92     return 0;
    93 }

    附上一链接:http://www.cppblog.com/notonlysuccess/archive/2009/03/03/75405.aspx

  • 相关阅读:
    hadoop2.2.0伪分布式搭建
    HBase详解
    Hbase常用命令
    hbase读取数据原理
    约瑟夫环
    哈希表设计
    哈夫曼树的建立
    TCP的连接和释放
    什么是Kmp算法?
    什么是https
  • 原文地址:https://www.cnblogs.com/wally/p/2939110.html
Copyright © 2020-2023  润新知