zoukankan      html  css  js  c++  java
  • hdoj 1588 学好线代与数学

    按部就班,超级简单,虽然不是一次过的。。。错在那个long long数据问题还是要注意。。也不知道要怎么注意;还是说题目吧。。。

    思路看main函数

    其他函数功能也是非常有用!代码比较丑。。。见谅

    #include <stdio.h>
    #include <iostream>
    #include <sstream>
    #include <string.h>
    #include <math.h>
    #include<stdlib.h>
    #include <queue>
    #include <set>
    #include <algorithm>
    using namespace std;

    long long mod;

    struct asd{
        long long a[4][4];
    };
    asd ak;                   //代表A的k次
    asd mul(asd x,asd y)      //矩阵乘法
    {
        int i,j,k;
        asd ans;
        for(i=0;i<2;i++)
        {
            for(j=0;j<2;j++)
            {
                ans.a[i][j]=0;
                for(k=0;k<2;k++)
                {
                    ans.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod;
                    ans.a[i][j]%=mod;
                }
            }
        }
        return ans;
    }

    asd add(asd x,asd y)   //矩阵加法
    {
        int i,j,k;
        asd ans;
        for(i=0;i<2;i++)
        {
            for(j=0;j<2;j++)
            {
                ans.a[i][j]=(x.a[i][j]+y.a[i][j])%mod;
            }
        }
        return ans;
    }
    asd quick(asd y,long long g)   //快速幂
    {
        asd x;
        int i,k,j;
        for(i=0;i<2;i++)
        {
            for(j=0;j<2;j++)
            {
                if(i==j)
                    x.a[i][i]=1;
                else
                    x.a[i][j]=0;
            }
        }
        while(g)
        {
            if(g%2==1)
                x=mul(x,y);
            y=mul(y,y);
            g/=2;
        }
        return x;
    }

    asd slove(long long z)    //计算S(n);S(n)代表A的1次加到A的n次;
    {
        if(z==1)
            return ak;
        asd ans=slove(z/2);
        asd cur;
        if(z%2==1)
        {
            cur=quick(ak,z/2+1);
            ans=add(ans,mul(ans,cur));
            ans=add(cur,ans);
        }
        else
        {
            cur=quick(ak,z/2);
            ans=add(ans,mul(ans,cur));
        }
        return ans;
    }
    /*反正就想算数一样,斐波那契的那个矩阵肯定知道(不知道出门左转去学一下矩阵快速幂),假设是A,那么也就是题目要求
    就是计算A的0+b次到A的k(n-1)+b次的和,次数的相加拆开就是相乘(不知道去复读初中),那么,把A的b次提出来,A^b(E+A^K+A^2K+...A^(n-1)K)
    然后把A^K看作整体就是什么!!!还不知道看main函数代码。。草稿纸上列一列就知道了。。。
    */
    int main()
    {
        long long k,b,n;
        while(~scanf("%lld%lld%lld%lld",&k,&b,&n,&mod))
        {
            asd fb,ea,ans,y,sk;
            ea.a[0][0]=1;ea.a[0][1]=0;   //单位矩阵
            ea.a[1][0]=0;ea.a[1][1]=1;
            y.a[0][0]=1;y.a[0][1]=1;
            y.a[1][0]=1;y.a[1][1]=0;
            fb=quick(y,b);         //求一个A的b次
            ak=quick(y,k);          //求一个A的K次
            sk=slove(n-1);          //求S(K);
            sk=add(sk,ea);          //把没加的E加上
            ans=mul(sk,fb);         //乘一波
            printf("%lld ",ans.a[0][1]);    //这里还是看你的线代怎么样了。。
        }
        return 0;
    }


    
  • 相关阅读:
    (转) 解析 char *p和 char[]
    Linux下C程序内存、内存对齐问题 (实战)
    关于子网划分的两个例子
    子网掩码与子网划分 (转载)
    A、B、C类地址及子网掩码学习笔记
    本机ip、127.0.0.1和0.0.0.0区别(转载)
    初识const
    流媒体协议
    i2c-tools的使用方法
    linux ——内存共享映射mmap和munmap
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934592.html
Copyright © 2011-2022 走看看