第一次使用正解AC一道难度正常(其实非常水)的蓝题

题目链接
众所周知,蓝色是水的颜色,所以这是道水题(doge)


前置知识

矩阵、快速幂、最大公因数。


矩阵

假设原矩阵为 ab
则矩阵有以下运算。

矩阵加法

一个一个加,即:
c_{i,j}=a_{i,j}+b_{i,j}

矩阵乘法

一行一列乘,即:
c_{i,j}=\sum^n_{k=1}a_{i,k}\times b_{k,j}

结合律

(ab)c=a(bc)

单位矩阵

主对角线上都为 1 的矩阵。
了解这些就够了。


快速幂

例:
2^{19}

  1. 先将指数化为二进制
    19=10011_2
  2. 再将底数不断平方
    2^1=2
    2^2=4
    4^2=16
    16^2=256
    256^2=65536
  3. 将对应的位置上乘上对应的权值
    2^{19}=65536\times4\times2=请自行计算

程序实现:

int ksm(int n,int m){
	int res=1;
	while(m){
		if(n%2==1) res=n*res;
		n=n*n;
		m/=2;
	}
	return res;
}

最大公约数

数论只会GCD。

太简单了,不讲。


思路梳理

让我们求 (f_n,f_m)
就相当于让我们求 f_{(n,m)}
别问我怎么知道的,问就是打表打出来的。
首先用求出 nm最大公因数
然后再用矩阵快速幂求出 f_{(n,m)}
实现方法:
计算矩阵

1\,\,\,\,1\\ 1\,\,\,\,0

(n,m)-1 次方。


代码实现

矩阵乘法核心代码

jz operator *(jz a,jz b){
	jz res={};
	for(int i=1;i<=2;i++){
		for(int j=1;j<=2;j++){
			int sum=0;
			for(int k=1;k<=2;k++){
				sum+=a.a[i][k]%mod*b.a[k][j]%mod;
				sum%=mod;
			}
			res.a[i][j]=sum%mod;
			res.a[i][j]%=mod;
		}
	}
	return res;
}

矩阵快速幂核心代码

jz ksm(jz a,int n){
	jz res={};
	res.a[1][1]=1;
	res.a[2][2]=1;
	while(n){
		if(n%2==1) res=a*res;
		a=a*a;
		n/=2;
	}
	return res;
}

最大公因数核心代码

int Gcd(int x,int y){
	if(y==0) return x;
	return Gcd(y,x%y);
}

最后,完整代码。

想要吗,不给

发AC代码是要被封号的!!!

3 个赞

赞!赞!

3 个赞

给了

1 个赞

谢谢!

1 个赞