矩阵系列 题解

1.洛谷 P1962 斐波那契数列

题意

大家都知道,斐波那契数列是满足如下性质的一个数列:

F n = { 1 ( n ≤ 2 ) F n − 1 + F n − 2 ( n ≥ 3 ) F_n = \left\{\begin{aligned} 1 \space (n \le 2) \\ F_{n-1}+F_{n-2} \space (n\ge 3) \end{aligned}\right. Fn={1 (n≤2)Fn−1+Fn−2 (n≥3)

请你求出 F n   m o d   1 0 9 + 7 F_n \bmod 10^9 + 7 Fnmod109+7 的值。

1 ≤ n < 2 63 1\le n < 2^{63} 1≤n<263。

思路

F i − 1 F i \] = \[ F i − 2 F i − 1 \] ⋅ \[ 0 1 1 1 \] \\begin{bmatrix} F_{i-1} \& F_{i} \\end{bmatrix} =\\begin{bmatrix} F_{i-2} \&F_{i-1} \\end{bmatrix}\\cdot \\begin{bmatrix} 0 \& 1\\\\ 1 \& 1 \\end{bmatrix} \[Fi−1Fi\]=\[Fi−2Fi−1\]⋅\[0111

2.SMOJ 数列1

题意

有一个数列:

f n = { 0 ( n ≤ 2 ) 7 f n − 1 + 6 f n − 2 + 4 × 3 n ( n ≥ 3 ) f_n = \left\{\begin{aligned} 0 \ (n \le 2) \\ 7f_{n-1}+6f_{n-2}+4\times 3^n \ (n\ge 3) \end{aligned}\right. fn={0 (n≤2)7fn−1+6fn−2+4×3n (n≥3)

请你求出 f n   m o d   1 0 9 + 7 f_n \bmod 10^9 + 7 fnmod109+7 的值。

3 ≤ n ≤ 1 0 9 3\le n \le 10^9 3≤n≤109。

思路

f i − 1 f i 4 × 3 i + 1 \] = \[ f i − 2 f i − 1 4 × 3 i \] ⋅ \[ 0 6 0 1 7 0 0 1 3 \] \\begin{bmatrix} f_{i-1} \& f_i \&4\\times3\^{i+1}\\end{bmatrix}=\\begin{bmatrix} f_{i-2} \& f_{i-1} \& 4\\times 3\^i\\end{bmatrix}\\cdot \\begin{bmatrix} 0 \& 6 \& 0\\\\ 1 \& 7 \& 0\\\\ 0 \& 1 \& 3 \\end{bmatrix} \[fi−1fi4×3i+1\]=\[fi−2fi−14×3i\]⋅ 010671003 ## 3.SMOJ 数列2 ### 题意 有一个数列: f n = { 0 ( n ≤ 2 ) 7 f n − 1 + 6 f n − 2 + 4 × 3 n + 5 n ( n ≥ 3 ) f_n = \\left\\{\\begin{aligned} 0 \\ (n \\le 2) \\\\ 7f_{n-1}+6f_{n-2}+4\\times 3\^n+5n \\ (n\\ge 3) \\end{aligned}\\right. fn={0 (n≤2)7fn−1+6fn−2+4×3n+5n (n≥3) 请你求出 f n   m o d   1 0 9 + 7 f_n \\bmod 10\^9 + 7 fnmod109+7 的值。 ### 思路 \[ f i − 1 f i 4 × 3 i + 1 5 ( i + 1 ) 5 \] = \[ f i − 2 f i − 1 4 × 3 i 5 i 5 \] ⋅ \[ 0 6 0 1 0 1 7 0 1 0 0 1 3 1 0 0 1 0 1 0 0 0 0 1 1 \] \\begin{bmatrix} f_{i-1} \& f_i \& 4\\times 3\^{i+1} \& 5(i+1) \& 5 \\end{bmatrix}= \\begin{bmatrix} f_{i-2} \& f_{i-1} \& 4\\times 3\^i \& 5i \& 5 \\end{bmatrix}\\cdot\\begin{bmatrix} 0 \& 6 \& 0 \& 1 \& 0\\\\ 1 \& 7 \& 0 \& 1 \& 0\\\\ 0 \& 1 \& 3 \& 1 \& 0\\\\ 0 \& 1 \& 0 \& 1 \& 0\\\\ 0 \& 0 \& 0 \& 1 \& 1 \\end{bmatrix} \[fi−1fi4×3i+15(i+1)5\]=\[fi−2fi−14×3i5i5\]⋅ 0100067110003001111100001 ## 4.SMOJ 幸运数 ### 题意 小明认为只有数字 4 4 4 和 7 7 7 是幸运数字,其他数字都不是。如果一个整数的每个数字都是幸运数字,那么该整数就是幸运整数。 给出一个数组 n u m b e r s 1... n numbers_{1...n} numbers1...n。 一个长度为 L L L 的幸运数列 A 0... L − 1 A_{0...L-1} A0...L−1 必须同时满足: 1. ∀ i ∈ \[ 0 , L ) \\forall i\\in\[0,L) ∀i∈\[0,L), A i A_i Ai 必须是幸运整数。 2. ∀ i ∈ \[ 0 , L ) \\forall i\\in\[0,L) ∀i∈\[0,L), A i A_i Ai 的最后一个数字必须等于 A \[ i + 1 \] A\[i+1\] A\[i+1\] 的第一个数字。 3. ∀ i ∈ \[ 0 , L ) \\forall i\\in\[0,L) ∀i∈\[0,L),至少存在一个下标 j j j 满足 A i = n u m b e r s j A_i=numbers_j Ai=numbersj。 输出有多少个不同的长度为L的幸运序列,答案模 1234567891 1234567891 1234567891。 对于两个长度都是L的幸运序列 A 0... L − 1 A_{0...L- 1} A0...L−1 和 B 0... L − 1 B_{0...L - 1} B0...L−1,他们被认为是不同序列的条件是: ∃ i , A i ≠ B i \\exist i,A_i\\neq B_i ∃i,Ai=Bi。 1 ≤ n ≤ 50 , 1 ≤ n u m b e r s i ≤ 1 0 9 , 1 ≤ L ≤ 1 0 9 1\\le n\\le 50,1\\le numbers_i\\le 10\^9,1\\le L\\le 10\^9 1≤n≤50,1≤numbersi≤109,1≤L≤109 ### 思路 对所有幸运数分类: 1. 4 4 4 头 4 4 4 尾 2. 4 4 4 头 7 7 7 尾 3. 7 7 7 头 4 4 4 尾 4. 7 7 7 头 7 7 7 尾 用一个桶 c n t cnt cnt 记个数。 令 f i , t y p e f_{i,type} fi,type 表示前 i i i 个幸运数组成的序列中,序列最后一个数种类为 t y p e ∈ \[ 1 , 4 \] type\\in \[1,4\] type∈\[1,4\] 的方案数。 那么容易写出转移式子: f i , 1 = f i − 1 , 1 ⋅ c n t 1 + f i − 1 , 3 ⋅ c n t 1 f_{i,1}=f_{i-1,1}\\cdot cnt_1+f_{i-1,3}\\cdot cnt_1 fi,1=fi−1,1⋅cnt1+fi−1,3⋅cnt1 f i , 2 = f i − 1 , 1 ⋅ c n t 2 + f i − 1 , 3 ⋅ c n t 2 f_{i,2}=f_{i-1,1}\\cdot cnt_2+f_{i-1,3}\\cdot cnt_2 fi,2=fi−1,1⋅cnt2+fi−1,3⋅cnt2 f i , 3 = f i − 1 , 2 ⋅ c n t 3 + f i − 1 , 4 ⋅ c n t 3 f_{i,3}=f_{i-1,2}\\cdot cnt_3+f_{i-1,4}\\cdot cnt_3 fi,3=fi−1,2⋅cnt3+fi−1,4⋅cnt3 f i , 4 = f i − 1 , 2 ⋅ c n t 4 + f i − 1 , 4 ⋅ c n t 4 f_{i,4}=f_{i-1,2}\\cdot cnt_4+f_{i-1,4}\\cdot cnt_4 fi,4=fi−1,2⋅cnt4+fi−1,4⋅cnt4 只需做 L L L 次 dp 即可,但是 L L L 最大去到 1 0 9 10\^9 109,显然会炸。由于操作单调,因此考虑矩阵快速幂优化: \[ f i , 1 f i , 2 f i , 3 f i , 4 \] = \[ f i − 1 , 1 f i − 1 , 2 f i − 1 , 3 f i − 1 , 4 \] ⋅ \[ c n t 1 c n t 2 0 0 0 0 c n t 3 c n t 4 c n t 1 c n t 2 0 0 0 0 c n t 3 c n t 3 \] \\begin{bmatrix} f_{i,1} \& f_{i,2} \& f_{i,3} \& f_{i,4} \\end{bmatrix}=\\begin{bmatrix} f_{i-1,1} \& f_{i-1,2} \& f_{i-1,3} \& f_{i-1,4} \\end{bmatrix}\\cdot\\begin{bmatrix} cnt_1 \& cnt_2 \& 0 \& 0\\\\ 0 \& 0 \& cnt_3 \& cnt_4\\\\ cnt_1 \& cnt_2 \& 0 \& 0\\\\ 0 \& 0 \& cnt_3 \& cnt_3 \\end{bmatrix} \[fi,1fi,2fi,3fi,4\]=\[fi−1,1fi−1,2fi−1,3fi−1,4\]⋅ cnt10cnt10cnt20cnt200cnt30cnt30cnt40cnt3 ### 代码 ```cpp #include using namespace std; #define ll long long const ll N=102,mod=1234567891; struct matrix { ll row,col; ll data[N][N]; matrix(ll r,ll c,ll isI) { row=r; col=c; memset(data,0,sizeof(data)); if(isI) { for(int i=1;i<=row;i++) data[i][i]=1; } } }; matrix operator * (const matrix &a,const matrix &b) { matrix c(a.row,b.col,0); for(int i=1;i<=a.row;i++) for(int j=1;j<=b.col;j++) for(int k=1;k<=a.col;k++) c.data[i][j]=(c.data[i][j]+a.data[i][k]*b.data[k][j]%mod+mod)%mod; return c; } matrix qpow_matrix(matrix a,ll k) { matrix ret(a.row,a.col,1); while(k) { if(k&1)ret=ret*a; a=a*a; k>>=1; } return ret; } ll n,m,a[N]; ll f[N][5],cnt[5]; ll type(string x) { ll sx=x.size(); x='*'+x; for(int i=1;i<=sx;i++) if(x[i]!='4'&&x[i]!='7')return 0; if(x[1]=='4'&&x[sx]=='4')return 1; else if(x[1]=='4'&&x[sx]=='7')return 2; else if(x[1]=='7'&&x[sx]=='4')return 3; else return 4; } vectorluk[N]; int main() { scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++) { string a; cin>>a; ll t=type(a); if(!t)continue; bool flag=1; for(auto x:luk[t]) { if(x==a) { flag=0; break; } } if(flag)luk[t].push_back(a),cnt[t]++; } matrix A(1,4,0); matrix B(4,4,0); for(int i=1;i<=n;i++) A.data[1][i]=cnt[i]; B.data[1][1]=B.data[3][1]=cnt[1]; B.data[1][2]=B.data[3][2]=cnt[2]; B.data[2][3]=B.data[4][3]=cnt[3]; B.data[2][4]=B.data[4][4]=cnt[4]; A=A*qpow_matrix(B,m-1); ll ans=0; for(int i=1;i<=4;i++) ans=(ans+A.data[1][i])%mod; printf("%lld",ans); return 0; } ``` ## 5.SMOJ 序列/CF691E Xor-sequences ### 题意 给定一个数集 A A A,现在你需要构造一个长度为 m m m 的序列 B B B,序列 B B B 的元素从数集 A A A 中任意挑选,要求 B B B 中任意相邻的两个数字的异或值二进制表示中 1 1 1 的个数是 3 3 3 的倍数,请问 B B B 的有多少种合法的构造方案?两种方案不同当且仅当存在 b i b_i bi 在 A A A 中的位置不同。 1 ≤ n ≤ 100 , 1 ≤ m ≤ 1 0 18 , 0 ≤ a i ≤ 1 0 18 1\\le n\\le 100,1\\le m\\le 10\^{18},0\\le a_i\\le 10\^{18} 1≤n≤100,1≤m≤1018,0≤ai≤1018 ### 思路 设 f i , j f_{i,j} fi,j 表示选择了 i i i 个数,最后一个数是 a j a_j aj 的方案数(注意数列可以乱序),那么有: f i , j = ∑ k = 1 n f i − 1 , k ⋅ A i , j f_{i,j}=\\sum_{k=1}\^{n}f_{i-1,k}\\cdot\\ A_{i,j} fi,j=k=1∑nfi−1,k⋅ Ai,j 其中 A i , j A_{i,j} Ai,j 表示: A i , j = \[ a j ⨁ a k   m o d   3 = 0 \] A_{i,j}=\\left \[a_j\\bigoplus a_k \\bmod3=0\\right \] Ai,j=\[aj⨁akmod3=0

中括号为艾弗森括号,不难发现 A A A 以对角线对称。

对于每个 ( i , j ) (i,j) (i,j),都要遍历 k ∈ [ 1 , n ] k\in[1,n] k∈[1,n] 来逐一比对一遍是否有 a j ⨁ a k   m o d   3 = 0 a_j\bigoplus a_k \bmod3=0 aj⨁akmod3=0。如此过程,实则与矩阵乘法的运算过程比较相似(这还是比较注意力惊人了,除非你对矩阵无比的熟悉)那么不妨使用矩阵快速幂优化了。最终答案就是:
a n s = ∑ d a t a ( A n − 1 ) ans=\sum data(A^{n-1}) ans=∑data(An−1)

d a t a ( M ) data(M) data(M) 表示一个矩阵 M M M 内所有元素。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=102,mod=1e9+7;
struct matrix
{
	ll row,col;
	ll data[N][N];
	matrix(ll r,ll c,ll isI)
	{
		row=r;
		col=c;
		memset(data,0,sizeof(data));
		if(isI)
		{
			for(int i=1;i<=row;i++)
			data[i][i]=1;
		}
	}
};
matrix operator * (const matrix &a,const matrix &b)
{
	matrix c(a.row,b.col,0);
	for(int i=1;i<=a.row;i++)
	for(int j=1;j<=b.col;j++)
	for(int k=1;k<=a.col;k++)
	c.data[i][j]=(c.data[i][j]+a.data[i][k]*b.data[k][j]%mod+mod)%mod;
	return c; 
}
matrix qpow_matrix(matrix a,ll k)
{
	matrix ret(a.row,a.col,1);
	while(k)
	{
		if(k&1)ret=ret*a;
		a=a*a;
		k>>=1;
	}
	return ret;
}
ll n,m,a[N];
ll popcnt(ll x)
{
	ll ret=0;
	while(x)
	{
		if(x&1)ret++;
		x>>=1;
	}
	return ret;
}
int main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++)
	scanf("%lld",&a[i]);
	matrix A(n,n,0);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	A.data[i][j]=(popcnt(a[i]^a[j])%3==0);
	A=qpow_matrix(A,m-1);
	ll ans=0;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	ans=(ans+A.data[i][j])%mod;
	printf("%lld",ans);
	return 0;
}

6.SMOJ 黑板与数字/CF621E Wet Shark and Blocks

(本篇较口胡,见谅)

题意

有 b b b 个黑板,从左往右排成一行。

第 1 1 1 个黑板从左往右写有 n n n 个数字,每个数字是 1 1 1 至 9 9 9 范围内的数字。

把第 1 1 1 个黑板的所有数字复制一份,写到第 2 2 2 个黑板。

把第 1 1 1 个黑板的所有数字复制一份,写到第 3 3 3 个黑板。

把第 1 1 1 个黑板的所有数字复制一份,写到第 b b b 个黑板。

从这 b b b 个黑板中,各取一个数字,构成一个 b b b 位数,要使得这个 b b b 位数模 x x x 的结果是 k k k,求方案数(同一个黑板内取相同的数字算不同方案,因为位置不同),答案模 1 0 9 + 7 10^9+7 109+7。

思路

令 f i , j f_{i,j} fi,j 表示选了 i i i 个格子,模 x x x 余数为 j j j,那么有转移式子:
f i , 10 j + k   m o d   x = f i − 1 , j + n u m ( k ) f_{i,10j+k \bmod x}=f_{i-1,j}+num(k) fi,10j+kmodx=fi−1,j+num(k)

其中 n u m ( k ) num(k) num(k) 表示: n u m ( k ) = ∑ i = 1 n [ a i   m o d   x = k ] num(k)=\sum_{i=1}^n [a_i\bmod x=k] num(k)=i=1∑n[aimodx=k]

再枚举每一位,去到了 Θ ( b x ) \Theta(bx) Θ(bx);但是如此操作,像上几篇题解一样,与矩阵乘法相类似,因此可以考虑矩阵快速幂优化到 Θ ( log ⁡ 2 b ) \Theta(\log_2b) Θ(log2b)

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=111,mod=1e9+7;
ll n,b,k,x,a,yx[N];
struct matrix
{
	ll row,col;//行和列
	ll data[N][N];
	matrix(ll r,ll c,ll isI)
	{
		row=r;
		col=c;
		memset(data,0,sizeof(data));
		if(isI)
		{
			for(int i=0;i<row;i++)
			data[i][i]=1;
		}
	}
};
matrix operator * (const matrix &a,const matrix &b)
{
	matrix c(a.row,b.col,0);
	for(int i=0;i<a.row;i++)
	for(int j=0;j<b.col;j++)
	for(int k=0;k<a.col;k++)
	c.data[i][j]=(c.data[i][j]+a.data[i][k]*b.data[k][j]%mod+mod)%mod;
	return c;
}
matrix qpow_matrix(matrix a,ll k)
{
	matrix res(a.row,a.col,1);
	while(k)
	{
		if(k&1)res=res*a;
		a=a*a;
		k>>=1;
	}
	return res;
}
int main()
{
	scanf("%lld%lld%lld%lld",&n,&b,&k,&x);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a);
		yx[a%x]++;
	}
	matrix A(1,x,0);
	for(int i=0;i<x;i++)
	A.data[0][i]=yx[i];
	matrix B(x,x,0);
	for(int i=0;i<x;i++)
	{
		for(int j=0;j<x;j++)
		{
			ll r=(i*10+j)%x;
			B.data[i][r]+=yx[j];
		}
	}
	A=A*qpow_matrix(B,b-1);
	printf("%lld",A.data[0][k]);
	return 0;
}
相关推荐
你要飞5 小时前
考研线代第三课:向量组
笔记·线性代数·考研·矩阵
aigcapi5 小时前
AI 获客系统哪个好?矩阵系统哪个好?2026 客观测评 TOP4
大数据·人工智能·矩阵
一碗姜汤1 天前
【统计基础】卡尔曼滤波,矩阵对迹求导,Joseph Form,条件数
线性代数·矩阵
sunfove1 天前
麦克斯韦方程组 (Maxwell‘s Equations) 的完整推导
线性代数·算法·矩阵
yyy(十一月限定版)1 天前
matlab矩阵的操作
算法·matlab·矩阵
ComputerInBook1 天前
代数学基本概念理解——幺正矩阵(Unitary matrix)(酉矩阵?)
线性代数·矩阵·正交矩阵·幺正矩阵·酉矩阵
AI科技星1 天前
光速飞行器动力学方程的第一性原理推导、验证与范式革命
数据结构·人工智能·线性代数·算法·机器学习·概率论
一碗姜汤1 天前
【统计基础】从线性代数的直观角度理解SVD奇异值分解
线性代数
好奇龙猫1 天前
【大学院-筆記試験練習:线性代数和数据结构(5)】
数据结构·线性代数
jinmo_C++1 天前
Leetcode矩阵
算法·leetcode·矩阵