• 距阵的运用


    昨晚大四的一个学长给我们讲了,距阵的使用,很不错,这里总结一下。

    一般距阵,用在n很大,导致超时的问题上。它需要快速幂取模的辅助。

    例子

    求斐波那契数列   a1=1;    a2=1;     an=an-1+an-2;   求 an     (n>=1&&n<=108)    由于n很大结果对999999999取模;

    对于这题n很大你直接推,每次取%999999999,明显会超时,

    矩阵做法

    这样就可以化为 矩阵(a1 a2)*矩阵(An-1)= 矩阵(an,an+1);

    看代码

    #include<stdio.h>
    #include<string.h>
    #define mod 999999999

    __int64 a[5];
    __int64 b[3][3];

    __int64 quick_mod(__int64 n)
    {
    a[1]=1; a[2]=1;
    b[1][1]=0; b[1][2]=1;
    b[2][1]=1; b[2][2]=1;
    while(n)
    {
    if(n&1)
    {
    __int64 s1,s2;
    s1=(a[1]*b[1][1]%mod+a[2]*b[2][1]%mod)%mod;
    s2=(a[1]*b[2][1]%mod+a[2]*b[2][2]%mod)%mod;
    a[1]=s1;
    a[2]=s2;
    n--;
    }
    n=n/2;
    __int64 k1,k2,k3,k4;
    k1=(b[1][1]*b[1][1]%mod+b[1][2]*b[2][1]%mod)%mod;
    k2=(b[1][1]*b[2][1]%mod+b[1][2]*b[2][2]%mod)%mod;
    k3=(b[2][1]*b[1][1]%mod+b[2][2]*b[2][1]%mod)%mod;
    k4=(b[2][1]*b[1][2]%mod+b[2][2]*b[2][2]%mod)%mod;
    b[1][1]=k1; b[1][2]=k2; b[2][1]=k3; b[2][2]=k4;
    }
    return a[1];
    }

    int main(void)
    {
    __int64 n;
    while(scanf("%I64d",&n)==1)
    {
    printf("%I64d ",quick_mod(n-1));
    }
    return 0;
    }

    这样就运用快速幂取模大大减少了时间。

    如果矩阵大一点的话这样写

    #include<stdio.h>
    #include<string.h>
    #define mod 999999999

    __int64 a[5];
    __int64 b[3][3];

    __int64 quick_mod(__int64 n)
    {
    __int64 i,j,k;
    a[1]=1; a[2]=1;
    b[1][1]=0; b[1][2]=1;
    b[2][1]=1; b[2][2]=1;
    while(n)
    {
    if(n&1)
    {
    __int64 s[3];
    memset(s,0,sizeof(s));
    for(i=1;i<=2;i++)
    {
    for(j=1;j<=2;j++)
    {
    s[i]=(s[i]+a[j]*b[j][i])%mod;
    }
    }
    for(i=1;i<=2;i++)
    a[i]=s[i];
    n--;
    }
    n=n/2;
    __int64 kk[5][5];
    memset(kk,0,sizeof(kk));
    for(i=1;i<=2;i++)
    {
    for(j=1;j<=2;j++)
    {
    for(k=1;k<=2;k++)
    {
    kk[i][j]=(kk[i][j]+b[i][k]*b[k][j])%mod;
    }
    }
    }
    for(i=1;i<=2;i++)
    {
    for(j=1;j<=2;j++)
    {
    b[i][j]=kk[i][j];
    }
    }
    }
    return a[1];
    }

    int main(void)
    {
    __int64 n;
    while(scanf("%I64d",&n)==1)
    {
    printf("%I64d ",quick_mod(n-1));
    }
    return 0;
    }

  • 相关阅读:
    SOD开源框架MSF(消息服务框架)介绍
    c#中foreach的一种用法
    MSSql异常处理框架
    什么是架构?有几人说的清楚
    MSSql动态行转列
    WebForm版demo,模拟手机Usb接口充电
    规范化流程不能窥探的咪咪
    我对领导者的定义
    以乞丐为最大的贵客
    程序猿,是如何逆袭的
  • 原文地址:https://www.cnblogs.com/liudehao/p/4148258.html
Copyright © 2020-2023  润新知