BZOJ1002洛谷P2144 [FJOI2007]轮状病毒

emmm据说是矩阵树,想想也是,但我不会。。

然后看到各个大神手画半小时,蹭蹭结果吧

1  5  16  45  121

emmm,诶,奇数项好像是平方数,偶数项,凝视30秒————偶数项是平方数-4,试一试?诶,44分,又分就不错,为啥呢?发现溢出,需要高精,所以我们写一个包括高精加乘的板子就好,递推关系,发现分f[i]=f[i-1]+f[i-2],先递推出第n项是什么数,然后高精平方,然后判断奇偶,偶数项-4就好

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=50006;
struct mtix
{
	int n[M];
	mtix(){memset(n,0,sizeof(n));}
}e[150];
int num;
mtix add(mtix a,mtix b)
{
	for (int i=1;i<=a.n[0];i++) a.n[i]+=b.n[i];
	for (int i=1;i<=a.n[0];i++)
	a.n[i+1]+=(a.n[i]/10),a.n[i]%=10;
	a.n[0]+=(a.n[a.n[0]]>0);
	return a; 
}
mtix mul(mtix a)
{
	mtix c;
	for (int i=1;i<=a.n[0];i++)
	{
		int up=0;
		for (int k=1;k<=a.n[0];k++)
		{
			c.n[i+k-1]+=a.n[i]*a.n[k]+up;
			up=c.n[i+k-1]/10;c.n[i+k-1]%=10;
		}
		c.n[i+a.n[0]]=up;
	}
	c.n[0]=a.n[0]*2;
	while (c.n[c.n[0]]==0&&c.n[0]>0) c.n[0]--;
	return c;
}
mtix sub(mtix a)
{
	if (a.n[1]>=4) a.n[1]-=4;
	else a.n[1]+=6,a.n[2]-=1;
	return a;
}
int main()
{
	scanf("%d",&num);
	e[1].n[0]=1;e[2].n[0]=1;
	e[1].n[1]=1;e[2].n[1]=3;
	for (int i=3;i<=num;i++)
		e[i]=add(e[i-1],e[i-2]);
	e[num]=mul(e[num]);
	if (num%2==0) e[num]=sub(e[num]);
	for (int i=e[num].n[0];i>0;i--)
		printf("%d",e[num].n[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/80910241