8.9上课感悟

数论课

今天讲数论诶……
表示今天数学讲课的课件还是没有要到……(下次我自己拷吧
话说今天数学讲的真心快,看看OB那边讲得多慢(我们这边放了那边才讲到线性筛)
那些什么线性求逆元之类的东西还是要自己慢慢复习的,感觉听一次忘一次
数论这些东西没什么感悟,主要是自己达到那个数学的理论水平就可以理解了
话说本来正常14:30下课回家……

矩阵

今天最重要的我个人认为是矩阵吧
废话不多说,直接切重点
矩阵的加减法没什么好说的吧
主要是乘法运用的比较多
见百度
这个公式可能比较抽象,不好理解
那么我们换个东西,变成矩阵的
见百度
那么这样矩阵乘法怎么做的就十分明显了
两个矩阵X(A*B),Y(B*C)相乘,大小为(A,C)
矩阵乘法必须满足X的列数=Y的行数
我们在做矩阵的时候,可以把这个矩阵抽象成一个数
显然,矩阵乘法满足结合律和交换律
通过这个性质,我们可以来做矩阵上的dp(后话)

我们来个例题吧
斐波那契数列为 f[n]=f[n-1]+f[n-2]
求出 f[n]%p的值 (N<=10^18)
暴力显然T到飞起……
我们可以构造矩阵
这里写图片描述
这显然满足矩阵乘法的性质
那么f[n]就能通过矩阵乘法得到
所以最终我们可以得到
这里写图片描述
然后矩阵快速幂即可
快速幂中途很可能会爆long long,所以建议慢速乘
注:矩阵快速幂和普通的数快速幂一样
来发个代码(不高兴慢速乘了)

struct matrix{
    int n,m;
    LL a[3][3];
    matrix(int x,int y,LL A,LL B,LL C,LL D){
        n=x,m=y;
        a[1][1]=A,a[1][2]=B;
        a[2][1]=C,a[2][2]=D;
    } 
};
matrix operator * (matrix x,matrix y){
    int N=x.n,M=y.m;
    matrix ret(N,M,0,0,0,0);
    for(int i=1;i<=N;i++)
        for(int j=1;j<=M;j++)
            for(int k=1;k<=x.m;k++)
                ret.a[i][j]=(ret.a[i][j]+x.a[i][k]*y.a[k][j])%p;
    return ret;
}
matrix Pow(matrix x,LL y){
    matrix ret=x,s=x;
    while(y){
        if(y&1) ret=ret*s;
        s=s*s;
        y>>=1;
    }
    return ret;
}
LL calc(int n){
    matrix tmp(2,2,1,1,1,0),mat(2,2,1,0,1,0);
    matrix ret=Pow(tmp,n-2)*mat;
    return ret.a[1][1]%p;
}

感觉蛮简单的,自己手动推推应该就能推出来
原来用jyg大神的算法跑10^18肯定T飞,但是一用矩阵速度是飞上去的
对于10^18的数据,矩阵轻松秒出,估计只要50-60ms
这速度简直是飞一般的感觉……

总结

我只总结矩阵这方面的东西
一般是用矩阵来优化递推式,第一步当然是求出递推式啦
完了之后建议先将后面的两个要求的矩阵先写出来,然后最前面的常数矩阵可以自己推
什么时候可以用矩阵优化呢?
一般是某个东西比较小,而且我们只要知道那一部分的东西就行了
所以这样矩阵的大小不会太大,时间也不会T

反正今天就是矩阵的入门,后面慢慢学,慢慢理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值