矩阵系列 题解

embedded/2025/3/1 4:23:58/

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 (n2)Fn1+Fn2 (n3)

请你求出 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} 1n<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} [Fi1Fi]=[Fi2Fi1][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 (n2)7fn1+6fn2+4×3n (n3)

请你求出 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 3n109

思路

[ 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} [fi1fi4×3i+1]=[fi2fi14×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 (n2)7fn1+6fn2+4×3n+5n (n3)

请你求出 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} [fi1fi4×3i+15(i+1)5]=[fi2fi14×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...L1 必须同时满足:

  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...L1 B 0... L − 1 B_{0...L - 1} B0...L1,他们被认为是不同序列的条件是: ∃ 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 1n50,1numbersi109,1L109

思路

对所有幸运数分类:

  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=fi1,1cnt1+fi1,3cnt1

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=fi1,1cnt2+fi1,3cnt2

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=fi1,2cnt3+fi1,4cnt3

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=fi1,2cnt4+fi1,4cnt4

只需做 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]=[fi1,1fi1,2fi1,3fi1,4] cnt10cnt10cnt20cnt200cnt30cnt30cnt40cnt3

代码

#include<bits/stdc++.h>
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;
}
vector<string>luk[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} 1n100,1m1018,0ai1018

思路

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=1nfi1,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=[ajakmod3=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 ajakmod3=0。如此过程,实则与矩阵乘法的运算过程比较相似(这还是比较注意力惊人了,除非你对矩阵无比的熟悉)那么不妨使用矩阵快速幂优化了。最终答案就是:
a n s = ∑ d a t a ( A n − 1 ) ans=\sum data(A^{n-1}) ans=data(An1)

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

#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=fi1,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=1n[aimodx=k]

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

代码

#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;
}

http://www.ppmy.cn/embedded/168960.html

相关文章

网络层ip协议

Ip协议报文格式 4 位版本号(version): 指定 IP 协议的版本, 对于 IPv4 来说, 就是 4. 4位头部长度(header length): IP头部的长度是多少个 32bit,也就是 length 4的字节数. 4bit 表示最大的数字是 15, 因此 IP 头部最大长度是 60 字节. 8 位服务类型(Type Of Service): 3 位…

鸿蒙兼容Mapbox地图应用测试

鸿蒙Next已经发布一段时间了&#xff0c;很多之前的移动端地图应用&#xff0c;纷纷都要求适配鸿蒙Next。作为开发者都清楚&#xff0c;所谓的适配其实都是重新开发&#xff0c;鸿蒙的开发语言和纯前端的Javascript不同&#xff0c;也可以Android原始开发的语言不同。鸿蒙自带的…

mysql的分区表

1.SQL表创建 下面以时间范围进行创建&#xff08;每月一个分区&#xff0c;表中创建了四个月的分区&#xff09; 创建&#xff1a;CREATE TABLE test_table ( id INT NOT NULL AUTO_INCREMENT, content VARCHAR(255), create_time DATETIME NOT NULL,PRIMARY KEY (id, cre…

【网络编程】几个常用命令:ping / netstat / xargs / pidof / watch

ping&#xff1a;检测网络联通 1. ping 的基本功能2. ping 的工作原理3. ping 的常见用法4. ping 的输出解释5. ping 的应用场景6. 注意事项 netstat&#xff1a;查看网络状态 1. netstat 的基本功能2. 常见用法3. 示例4. 输出字段解释5. netstat 的替代工具6. 注意事项 xargs&…

【华为OD机考】华为OD笔试真题解析(15)--异常的打卡记录

题目描述 考勤记录是分析和考核职工工作时间利用情况的原始依据&#xff0c;也是计算职工工资的原始依据&#xff0c;为了正确地计算职工工资和监督工资基金使用情况&#xff0c;公司决定对员工的手机打卡记录进行异常排查。 如果出现以下两种情况&#xff0c;则认为打卡异常…

Nginx 报错:413 Request Entity Too Large

做web开发时&#xff0c;对于上传附件的功能&#xff0c;如果nginx没有调整配置&#xff0c;上传大一点的文件就会发生下面这种错误&#xff1a; 要解决上面的问题&#xff0c;只需要调整Nginx配置文件中的 client_max_body_size 参数即可&#xff0c;这个配置参数一般在http配…

行为型模式 - 职责链模式 (Chain of Responsibility Pattern)

行为型模式 - 职责链模式 (Chain of Responsibility Pattern) 职责链模式是一种行为设计模式&#xff0c;它允许你将请求沿着处理者链进行传递&#xff0c;直到有一个处理者能够处理该请求为止。以下是几个职责链模式的经典案例。 在企业中&#xff0c;员工请假需要不同级别的…

学习路程八 langchin核心组件 Models补充 I/O和 Redis Cache

前序 之前了解了Models&#xff0c;Prompt&#xff0c;但有些资料又把这块与输出合称为模型输入输出&#xff08;Model I/O&#xff09;‌&#xff1a;这是与各种大语言模型进行交互的基本组件。它允许开发者管理提示&#xff08;prompt&#xff09;&#xff0c;通过通用接口调…