• CSU 1208: Fibonacci sum


    题目链接:http://122.207.68.93/OnlineJudge/problem.php?id=1208

    比赛的时候只是觉得是矩阵,但是一直没想到怎么推...(a+b)^k应该联想到二项式的啊ToT,而且他说k<=20,明摆着就是告诉你可以矩阵的...正确的构造方法是:

                                                                                         C(k,0)  c(k-1,0)  C(k-2,0)...C(0,0) C(k,0)

                                    C(k,1)  c(k-1,1)  C(k-2,1)...    0    C(k,1)

    [ fib(n-1)k,fib(n-1)k-1fib(2).....fib(n-2)k,sum[n-1] ] *        .......

                                      C(k,k)       0             0    ...     0    C(k,K)

                                       0          0             0    ...     0        1  

    CSU 1208
    #include<stdio.h>
    #include<string.h>
    #define MOD 1000000007
    #define maxn 25
    long long C[25][25];
    long long ret[maxn][maxn];
    long long init[maxn][maxn];
    long long buf[maxn][maxn];
    
    void matrixMul(long long a[][maxn] , long long b[][maxn] , long long n,long long mod)
    {
        long long i,j,k;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                buf[i][j]=0;
            }
        }
        for(i=0;i<n;i++)
        {
            for(k=0;k<n;k++)
            {
                if(a[i][k]==0)
                    continue;
                for(j=0;j<n;j++)
                {
                    if(b[k][j]==0)
                        continue;
                    buf[i][j]+=a[i][k]*b[k][j];
                    if (buf[i][j]>=mod||buf[i][j]<=-mod)
                    {
                        buf[i][j]%=mod;
                    }
                }
            }
        }
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                a[i][j]=buf[i][j];
            }
        }
    }
    
    void matrixMul(long long n,long long m,long long mod)
    {
        long long i,j;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                ret[i][j]=(i==j);
            }
        }
        for(;m;m>>=1)
        {
            if(m&1)
            {
                matrixMul(ret,init,n,mod);
            }
            matrixMul(init,init,n,mod);
        }
    }
    
    void initc()
    {
        C[0][0]=C[1][0]=C[1][1]=1;
         for(int i=2;i<=20;i++)
         {
             for(int j=0;j<=i&&j<=20;j++)
             {
                 if(j==0)
                     C[i][j]=1;
                 else
                     C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
             }
         }
    }
    
    int main()
    {
        initc();
        int t,n,k,i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&k);
            if(n==1)
            {
                printf("1\n");
                continue;
            }
            else if(n==2)
            {
                printf("2\n");
                continue;
            }
            memset(init,0,sizeof(init));
            for(i=0;i<=k;i++)
            {
                for(j=0;j<=k-i;j++)
                {
                    init[j][i]=C[k-i][j];
                }
            }
            for(i=0;i<=k;i++)
            {
                init[i][k+1]=C[k][i];
            }
            init[k+1][k+1]=1;
            matrixMul(k+2,n-2,MOD);
            long long ans=0;
            for(i=0;i<=k;i++)
            {
                ans=(ans+ret[i][k+1])%MOD;
            }
            ans=(ans+2*ret[k+1][k+1])%MOD;
            printf("%lld\n",ans);
        }
        return 0;
    }

      哎,以此题为记,不能再被表面现象吓到了><           

    下面为升级版,可以用做练习:

    hdu 3509.Buge's Fibonacci Number Problem

    HDU 3509
    #include<stdio.h>
    #include<string.h>
    int MOD;
    #define maxn 55
    long long C[55][55],A[55],B[55],F1[55],F2[55];
    long long ret[maxn][maxn];
    long long init[maxn][maxn];
    long long buf[maxn][maxn];
    
    void matrixMul(long long a[][maxn] , long long b[][maxn] , long long n,long long mod)
    {
        long long i,j,k;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                buf[i][j]=0;
            }
        }
        for(i=0;i<n;i++)
        {
            for(k=0;k<n;k++)
            {
                if(a[i][k]==0)
                    continue;
                for(j=0;j<n;j++)
                {
                    if(b[k][j]==0)
                        continue;
                    buf[i][j]+=a[i][k]*b[k][j];
                    if (buf[i][j]>=mod||buf[i][j]<=-mod)
                    {
                        buf[i][j]%=mod;
                    }
                }
            }
        }
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                a[i][j]=buf[i][j];
            }
        }
    }
    
    void matrixMul(long long n,long long m,long long mod)
    {
        long long i,j;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                ret[i][j]=(i==j);
            }
        }
        for(;m;m>>=1)
        {
            if(m&1)
            {
                matrixMul(ret,init,n,mod);
            }
            matrixMul(init,init,n,mod);
        }
    }
    
    void initc(int k)
    {
        C[0][0]=C[1][0]=C[1][1]=1;
         for(int i=2;i<=k;i++)
         {
             for(int j=0;j<=i&&j<=k;j++)
             {
                 if(j==0)
                     C[i][j]=1;
                 else
                     C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
             }
         }
    }
    
    
    int main()
    {
        long long t,n,k,i,j,f1,f2,a,b;
        scanf("%I64d",&t);
        while(t--)
        {
            scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&f1,&f2,&a,&b,&k,&n,&MOD);
            initc(k);
            long long ans=0;
            F1[0]=F2[0]=1;
            for(i=1;i<=k;i++)
            {
                F1[i]=(F1[i-1]*f1)%MOD;
                F2[i]=(F2[i-1]*f2)%MOD;
            }
            if(n==1)
            {
                ans=F1[k];
                printf("%I64d\n",ans);
                continue;
            }
            else if(n==2)
            {
                ans=F1[k];
                ans=(ans+F2[k])%MOD;
                printf("%I64d\n",ans);
                continue;
            }
            memset(init,0,sizeof(init));
            A[0]=B[0]=1;
            for(i=1;i<=k;i++)
            {
                A[i]=(A[i-1]*a)%MOD;
                B[i]=(B[i-1]*b)%MOD;
            }
            for(i=0;i<=k;i++)
            {
                for(j=0;j<=k-i;j++)
                {
                    if(j>k-i)
                        init[j][i]=0;
                    else
                        init[j][i]=((C[k-i][j]*A[k-i-j])%MOD*B[j])%MOD;
                }
            }
            for(i=0;i<=k;i++)
            {
                init[i][k+1]=((C[k][i]*A[k-i])%MOD*B[i])%MOD;
            }
            init[k+1][k+1]=1;
            matrixMul(k+2,n-2,MOD);
            for(i=0;i<=k;i++)
            {
                ans=(ans+((F2[k-i]*F1[i])%MOD)*ret[i][k+1])%MOD;
            }
            long long temp;
            temp=F1[k];
            temp=(temp+F2[k])%MOD;
            ans=(ans+(temp*ret[k+1][k+1])%MOD)%MOD;
            printf("%I64d\n",ans);
        }
        return 0;
    }

                         

  • 相关阅读:
    pthread线程内存布局
    用户空间实现线程 内核实现线程 线程的调度
    堆 虚拟内存
    Operating System-Thread(3)用户空间和内核空间实现线程
    Linux进程地址空间与虚拟内存
    虚拟地址
    物理内存,虚拟内存,进程地址空间
    CPU中MMU的作用
    进程地址空间与虚拟存储空间的理解
    虚拟地址空间
  • 原文地址:https://www.cnblogs.com/SolarWings/p/3000279.html
Copyright © 2020-2023  润新知