zoukankan      html  css  js  c++  java
  • 2017 Multi-University Training Contest

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

    题意:题目很短自己看吧,

        就是这个递推式子,说的很清楚了,让你求F(m,1)。题解里面分什么奇偶性分别去算,有些人找规律找出来了,题解是非常严谨的用数学推出来了(反正没有看懂),虽然也用到了矩阵快速幂。

    思路:拿到这个题,我第一反应也是矩阵快速幂,然后手推了第二行,我发现第二行依旧满足上面F(2,i)=F(2,i-1)+2*F(2,i-2)这个性质。所以我就萌生一个想法,我先把一行算出来,然后把他转换成下一行。问题是如何在行与行之间转换,我们发现每一行的第一个等于上一个行1到n每一项之和,每一行的第二个,需要2到n+1每一项之和。那么我直接算出前n+1项的和Sn+1,Sn+1-Fn+1=N1,Sn+1-F1=N2。如此我们就得到了下一行的前两个。然后我们有可以同理求出再下一行。这个矩阵比较难构造,具体的矩阵是4*4的,为了说明方便,我在代码直接每一项赋值,可以把他们抄出来看看是否是这么一个回事,构造矩阵可能是一个难点,我做了挺多矩阵快速幂的题,有一些小经验,以后可能会写出来分享一下。

    代码:

     1 //Author: xiaowuga
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <set>
     5 #include <vector>
     6 #include <queue>
     7 #include <cmath>
     8 #include <cstring>
     9 #include <cstdio>
    10 #include <ctime>
    11 #include <map>
    12 #include <bitset>
    13 #include <cctype>
    14 #define maxx INT_MAX
    15 #define minn INT_MIN
    16 #define inf 0x3f3f3f3f
    17 #define mem(s,ch) memset(s,ch,sizeof(s))
    18 #define da cout<<da<<endl
    19 #define uoutput(a,i,l,r) for(int i=l;i<r;i++) if(i==l) cout<<a[i];else cout<<" "<<a[i];cout<<endl;
    20 #define doutput(a,i,l,r) for(int i=r-1;i>=0;i--) if(i==r-1) cout<<a[i];else cout<<" "<<a[i];cout<<endl;
    21 const long long N=4;
    22 const long long mod=1e9+7;
    23 using namespace std;
    24 typedef long long LL;
    25 struct Matrix{
    26     LL mat[N][N] = {{0}};
    27     void clear(){
    28         memset(mat,0,sizeof(mat));
    29     }
    30     Matrix operator * (const Matrix & m) const{
    31         Matrix tmp;
    32         for(int i=0;i<N;i++)
    33             for(int k=0;k<N;k++){
    34                 if (mat[i][k]) {
    35                     for(int j=0;j<N;j++){
    36                         tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%mod;
    37                         tmp.mat[i][j]%=mod;
    38                     }
    39                 }
    40             }
    41         return tmp;
    42     }
    43 };
    44 Matrix POW(Matrix m,LL k){
    45     Matrix ans;
    46     ans.clear();
    47     for(int i=0;i<N;i++) ans.mat[i][i]=1;
    48     while(k){
    49         if(k&1) ans=ans*m;
    50         k/=2;
    51         m=m*m;
    52     }
    53     return ans;
    54 }
    55 Matrix xx,yy;
    56 void init(){
    57     xx.mat[0][0]=1; xx.mat[0][1]=2; xx.mat[0][2]=0; xx.mat[0][3]=0;
    58     xx.mat[1][0]=1; xx.mat[1][1]=0; xx.mat[1][2]=0; xx.mat[1][3]=0;
    59     xx.mat[2][0]=1; xx.mat[2][1]=2; xx.mat[2][2]=1; xx.mat[2][3]=0;
    60     xx.mat[3][0]=0; xx.mat[3][1]=0; xx.mat[3][2]=0; xx.mat[3][3]=1;
    61 
    62     yy.mat[0][0]=0; yy.mat[0][1]=0; yy.mat[0][2]=1; yy.mat[0][3]=mod-1;
    63     yy.mat[1][0]=mod-1; yy.mat[1][1]=0; yy.mat[1][2]=1; yy.mat[1][3]=0;
    64     yy.mat[2][0]=mod-1; yy.mat[2][1]=0; yy.mat[2][2]=2; yy.mat[2][3]=mod-1;
    65     yy.mat[3][0]=mod-1; yy.mat[3][1]=0; yy.mat[3][2]=1; yy.mat[3][3]=0;
    66 }
    67 LL n,mm;
    68 int main() {
    69     init();
    70     int T;
    71     scanf("%lld",&T);
    72     while(T--){
    73         scanf("%lld%lld",&n,&mm);
    74         if(n==1||mm==1) {cout<<1<<"
    ";continue;}
    75         Matrix ans1=POW(xx,n-1);
    76         Matrix ans2=ans1*yy;
    77         Matrix ans3=POW(ans2,mm);
    78         LL f[4]={1,1,2,1};
    79         LL a[4]={0};
    80         for(int i=0;i<4;i++){
    81             for(int j=0;j<4;j++){
    82                 a[i]+=ans3.mat[i][j]*f[j]%mod;
    83                 a[i]%=mod;
    84             }
    85         }
    86         cout<<a[3]<<"
    ";
    87     }
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    ASP.NET面试题(二)
    iBatis.Net系列(四) iBatisNet API基础
    ibatisnet系列(一) 总览
    iBatisnet系列(二) 配置运行环境和日志处理
    HDU 1575 Tr A (矩阵乘法)
    HDU 连连看
    1504: ZZ的橱柜 (优先队列)
    离散化思想
    POJ 2777 Count Color (线段树)
    POJ 1823 Hotel (线段树)
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7261099.html
Copyright © 2011-2022 走看看