您的位置:首页 > 其它

8.9上课感悟

2017-08-09 21:03 225 查看

数论课

今天讲数论诶……

表示今天数学讲课的课件还是没有要到……(下次我自己拷吧)

话说今天数学讲的真心快,看看OB那边讲得多慢(我们这边放了那边才讲到线性筛)

那些什么线性求逆元之类的东西还是要自己慢慢复习的,感觉听一次忘一次

数论这些东西没什么感悟,主要是自己达到那个数学的理论水平就可以理解了

话说本来正常14:30下课回家……

矩阵

今天最重要的我个人认为是矩阵吧

废话不多说,直接切重点

矩阵的加减法没什么好说的吧

主要是乘法运用的比较多



这个公式可能比较抽象,不好理解

那么我们换个东西,变成矩阵的



那么这样矩阵乘法怎么做的就十分明显了

两个矩阵X(A*B),Y(B*C)相乘,大小为(A,C)

矩阵乘法必须满足X的列数=Y的行数

我们在做矩阵的时候,可以把这个矩阵抽象成一个数

显然,矩阵乘法满足结合律和交换律

通过这个性质,我们可以来做矩阵上的dp(后话)

我们来个例题吧

斐波那契数列为 f
=f[n-1]+f[n-2]

求出 f
%p的值 (N<=10^18)

暴力显然T到飞起……

我们可以构造矩阵



这显然满足矩阵乘法的性质

那么f
就能通过矩阵乘法得到

所以最终我们可以得到



然后矩阵快速幂即可

快速幂中途很可能会爆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

反正今天就是矩阵的入门,后面慢慢学,慢慢理解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: