求助矩阵加速斐波那契,本地RE提交AC
  • 板块学术版
  • 楼主JRzyh
  • 当前回复2
  • 已保存回复2
  • 发布时间2021/2/2 14:41
  • 上次更新2023/11/5 03:56:52
查看原帖
求助矩阵加速斐波那契,本地RE提交AC
242524
JRzyh楼主2021/2/2 14:41

模板有点长。

#include<bits/stdc++.h>
#define mod (int(1e9+7))
using namespace std;
struct mat
{
	int n,m;
	long long/*int*/ z[233][233];
	mat()
	{
		n=m=0;
		memset(z,0,sizeof(z));
	}
	mat(int _n,int _m)
	{
		n=_n,m=_m;
		memset(z,0,sizeof(z));
	}
	long long/*int*/ * operator [] (int b)
	{
		return (this)->z[b];
	}
};
const mat error(-1,-1);
mat makeI(int n)
{
	mat c;
	c.m=c.n=n;
	for(int i=1;i<=n;i++)
	{
		c.z[i][i]=1;
	}
	return c;
}
mat make0(int n,int m)
{
	mat c;
	c.m=m;c.n=n;
	return c;
}
bool is0(const mat &a)
{
	if(a.m==-1||a.n==-1)return 0;
	for(int i=1;i<=a.n;i++)
	{
		for(int j=1;j<=a.m;j++)
		{
			if(a.z[i][j]!=0)return 0;
		}
	}
	return 1;
}
bool isI(const mat &a)
{
	if(a.m==-1||a.n==-1)return 0;
	if(a.m!=a.n)return 0;
	for(int i=1;i<=a.n;i++)
	{
		if(a.z[i][i]!=1)return 0;
	}
	for(int i=1;i<=a.n;i++)
	{
		for(int j=1;j<=a.m;j++)
		{
			if(i==j)continue;
			if(a.z[i][j]!=0)return 0;
		}
	}
	return 1;
}
bool isdj(const mat &a)
{
	if(a.m==-1||a.n==-1)return 0;
	if(a.m!=a.n)return 0;
	for(int i=1;i<=a.n;i++)
	{
		for(int j=1;j<=a.m;j++)
		{
			if(i==j)continue;
			if(a.z[i][j]!=0)return 0;
		}
	}
	return 1;
}
mat operator * (const mat &a,const mat &b)
{
	if(a.m==-1||a.n==-1||b.m==-1||b.n==-1)return error;
	if(a.m!=b.n)return error;
	mat c;
	c.n=a.n;c.m=b.m;
	for(int i=1;i<=c.n;i++)
	{
		for(int j=1;j<=c.m;j++)
		{
			for(int k=1;k<=a.m;k++)
			{
				c.z[i][j]+=a.z[i][k]%mod*b.z[k][j]%mod;
				c.z[i][j]%=mod;
			}
		}
	}
	return c;
}
mat operator + (const mat &a,const mat &b)
{
	if(a.m==-1||a.n==-1||b.m==-1||b.n==-1)return error;
	if(a.n!=b.n||a.m!=b.m)return error;
	mat c;
	c.n=a.n;c.m=a.m;
	for(int i=1;i<=c.n;i++)
	{
		for(int j=1;j<=c.m;j++)
		{
			c.z[i][j]=a.z[i][j]+b.z[i][j];
		}
	}
	return c;
}
mat operator - (const mat &a,const mat &b)
{
	if(a.m==-1||a.n==-1||b.m==-1||b.n==-1)return error;
	if(a.n!=b.n||a.m!=b.m)return error;
	mat c;
	c.n=a.n;c.m=a.m;
	for(int i=1;i<=c.n;i++)
	{
		for(int j=1;j<=c.m;j++)
		{
			c.z[i][j]=a.z[i][j]-b.z[i][j];
		}
	}
	return c;
}
mat operator * (const mat &a,const int &b)
{
	if(a.m==-1||a.n==-1)return error;
	mat c;
	c.n=a.n;c.m=a.m;
	for(int i=1;i<=c.n;i++)
	{
		for(int j=1;j<=c.m;j++)
		{
			c.z[i][j]=a.z[i][j]*b;
		}
	}
	return c;
}
bool operator == (const mat &a,const mat &b)
{
	if(a.m==-1||a.n==-1||b.m==-1||b.n==-1)return 0;
	if(a.m!=b.m||a.n!=b.n)return 0;
	for(int i=1;i<=a.n;i++)
	{
		for(int j=1;j<=a.m;j++)
		{
			if(a.z[i][j]!=b.z[i][j])return 0;
		}
	}
	return 1;
}
bool operator != (const mat &a,const mat &b){return !(a==b);}
void operator += (mat &a,const mat &b){a=a+b;}
void operator -= (mat &a,const mat &b){a=a-b;}
void operator *= (mat &a,const mat &b){a=a*b;}
void operator *= (mat &a,const int &b){a=a*b;}
mat ksm(mat a,long long b)
{
	if(a.m!=a.n)return error;
	mat res=makeI(a.n),ans=a;
	while(b)
	{
		if(b&1)res=res*ans;
		ans=ans*ans;
		b>>=1;
	}
	return res;
}
long long n;
int main()
{
 	mat a(1,2);
 	a.z[1][1]=a.z[1][2]=1;
 	mat b(2,2);
 	b[1][1]=b[1][2]=b[2][1]=1;
 	cin>>n;
 	if(n<=2)
	{
		cout<<1;
		return 0; 
	}
 	mat x=ksm(b,n-2);
 	x=a*x;
 	cout<<x[1][1];
	return 0;
}

注释的地方改成int就能不RE。

RE返回值显示是爆栈

2021/2/2 14:41
加载中...