1.“取模”运算法则
1. ( a + b ) % c = ( ( a % c ) + ( b % c ) ) % c
2. ( a * b ) % c = ( ( a % c ) * ( b % c ) ) % c
3. ( a – b ) % c = ( ( a % c ) – ( b % c ) ) % c
2.位运算
判断奇偶
x%2==1可以使用x&1==1代替,x%2==0可以使用x&1==0代替
x=x/2可以使用x>>=1代替,意为把x的二进制向右移动1位
x=x*2可以使用x<<=1代替,意为把x的二进制向左移动1位
PS:如果是x>>=y,意为x=x/(2^y)
3.大佬的快速幂最终模板
long long fastPower(long long base, long long power) {//base为底数,power为指数
long long result = 1;
while (power > 0) {
if (power & 1) {//此处等价于if(power%2==1)
result = result * base % 1000;//%1000是取结果的后三位,根据题目要求变化
}
power >>= 1;//此处等价于power=power/2
base = (base * base) % 1000;
}
return result;
}
矩阵定义:由 m × n 个数aij排成的m行n列的数表称为m行n列的矩阵,简称m × n矩阵。记作:
单位矩阵:在矩阵的乘法中,有一种矩阵起着特殊的作用,如同数的乘法中的1,这种矩阵被称为单位矩阵。它是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为1。除此以外全都为0。
矩阵乘法:两个矩阵的乘法仅当第一个矩阵A的列数和另一个矩阵B的行数相等时才能定义。如A是m×n矩阵和B是n×p矩阵,它们的乘积C是一个m×p矩阵
例如:
深入了解矩阵乘法:https://blog.csdn.net/zh_94/article/details/81571092
PS:在写矩阵快速幂的题目时,一般是做A(nxn)^m这样的运算,求nxn的矩阵A的m次幂,例如:
[1 2 3]
A=[4 5 6]
[7 8 9]
A是一个3x3的矩阵,求A^2,即
[1 2 3] [1 2 3] [C11 C12 C13]
[4 5 6] x [4 5 6] =C矩阵[C21 C22 C23]
[7 8 9] [7 8 9] [C31 C32 C33]
由于我们一般使用二维数组储存矩阵A,计算时也会是一个点一个点的去求解
求解法则:第1个矩阵A当前点的行x第2个矩阵A当前点的列
例如:C21=(4 5 6)*(1 4 7)
=4*1+5*4+6*7
=66
f(n)=a1*f(n-1)+a2*f(n-2)+a3*f(n-3);
给出a1,a2,a3,f1,f2,f3的值,让你求解f(n)%m
首先要把普通递推式变为矩阵递推式,即
先把普通递推式变为矩阵,然后找到一个矩阵A,使左边矩阵*A能变为左边矩阵的下一个状态,如下
【f(n-1),f(n-2),f(n-3)】*A=【f(n),f(n-1),f(n-2)】
可变为
【f(n-1),f(n-2),f(n-3)】*A=【a1*f(n-1)+a2*f(n-2)+a3*f(n-3),f(n-1),f(n-2)】
然后构建一个3x3得矩阵A:
【A11,A12,A13】
【A21,A22,A23】
【A31,A32,A33】
依据矩阵乘法,即可填出矩阵A,为
【a1,1,0】
【a2,0,1】
【a3,0,0】
如此,求f(n)即可变为
S(n)=A^(n-1)*S1
S1为初始矩阵,Sn为最后的矩阵
我们只需做核心的矩阵A的n-1次幂,题目就转化为快速幂算法了
练习题:
http://poj.org/problem?id=3070
#include"iostream"
#include"string.h"
#include"algorithm"
using namespace std;
typedef long long ll;
struct Matrix{
ll mat[10][10];
}start;
Matrix MUL(Matrix x,Matrix y){
Matrix z;
memset(z.mat,0,sizeof(z.mat));
for(int i=1;i<=2;i++){
for(int j=1;j<=2;j++){
for(int k=1;k<=2;k++){
z.mat[i][j] =(z.mat[i][j] + x.mat[i][k] * y.mat[k][j]%10000)%10000;
}
}
}
return z;
}
ll fastpower(Matrix x,ll n){
Matrix res;
memset(res.mat,0,sizeof(res.mat));
for(int i=1;i<=2;i++){//单位矩阵对角线赋值1,其余全为0,单位矩阵相当于数值中的1
res.mat[i][i]=1;
}
while(n){
if(n&1){
res=MUL(x,res);
}
x=MUL(x,x);
n>>=1;
}
return res.mat[1][2]%10000;
}
int main()
{
ll w;
while(cin>>w){
if(w==-1){
break;
}
start.mat[1][1]=start.mat[1][2]=start.mat[2][1]=1;
start.mat[2][2]=0;
cout<
矩阵题集:
https://vjudge.net/contest/71746