covering 矩阵快速幂模板
在寻找递推关系的过程中运用到了 已知前几项,暴力求通项公式的方法
因为知道通项公式右边一定是4项,因此暴力-100到100枚举每一项的系数,直至得到正确的公式
an=an−1+5an−2+an−3−an−4
用下矩阵快速幂处理,注意结果可能是负的,因此要进行特殊取模
以下是其他人做法
杜教筛?
http://blog.csdn.net/cww97/article/details/77753648
高斯消元?http://blog.csdn.net/d12155214552/article/details/77751796
dfs?暴力 http://blog.csdn.net/xs18952904/article/details/77727431
#include <iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 10;
const int mod1 = 1000000007 ;
const int mod2 = 2000000014 ;
struct mat//矩阵结构体,a表示内容,size大小 矩阵从1开始
{
ll a[maxn][maxn],size;
mat()
{
size=6;
memset(a,0,sizeof(a));
}
};
/*void print1(mat m)//输出矩阵信息,debug用 { int i,j; printf("%d\n",m.size); for(i=1; i<=m.size; i++) { for(j=1; j<=m.size; j++)printf("%d ",m.a[i][j]); printf("\n"); } }*/
mat multi(mat m1,mat m2)//两个相等矩阵的乘法,对于稀疏矩阵,有0处不用运算的优化
{
mat ans=mat();
ans.size=m1.size;
for(int i=1; i<=m1.size; i++)
for(int j=1; j<=m2.size; j++)
if(m1.a[i][j])//稀疏矩阵优化
for(int k=1; k<=m1.size; k++)
ans.a[i][k]=(ans.a[i][k]+m1.a[i][j]*m2.a[j][k])%mod1;
return ans;
}
mat pow1(mat m,long long n)//二分快速幂
{
mat ans=mat();
int i;
for(i=1; i<=m.size; i++)ans.a[i][i]=1;
ans.size=m.size;
while(n>0)
{
if(n&1)ans=multi(m,ans);
m=multi(m,m);
n>>=1;
}
return ans;
}
int main()
{
long long n;
while(~scanf("%lld",&n))
{
if(n==1)printf("1\n");
else if(n==2)printf("5\n");
else if(n==3)printf("11\n");
else
{
// n = n-3;
mat A,A1;
A.a[1][1] = 1;
A.a[1][2] = 5;
A.a[1][3] = 1;
A.a[1][4] = -1;
A.a[2][1] = 1;
A.a[3][2] = 1;
A.a[4][3] = 1;
A.a[5][4] = 1;
// print1(A);
A = pow1(A,n-3);
//print1(A);
A1.a[1][1] =11;
A1.a[2][1] = 5;
A1.a[3][1] = 1;
A1.a[4][1] = 1;
A1.a[5][1] = 1;
//print1(A1);
A1 = multi(A,A1);
// print1(A1);
cout<<(A1.a[1][1]+mod1)%mod1<<endl;
//注意这里的取mod,因为矩阵里有负数,所以在这里要进行取mod
}
}
}