Description
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示
N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
同的3轮状病毒,如下图所示
现给定n(N<=100),编程计算有多少个不同的n轮状病毒
Input
第一行有1个正整数n
Output
计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
Solution
看了题解发现什么矩阵树。。。
然后觉得这个题真的是。。。没什么好说的。
画了半天的图,把1,2,3,4的画出来了,貌似是1,5,9,45.。。
然后打了个表,发现5是121.
于是猜想性质,(f[1]=1,f[2]=3,f[x]=f[x-1]+f[x-2],ans=f[x]^2-(x%2==0)?$ 4:0)$.
套上高精,A了。。。。
Code
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#define re register
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(arr) memset(arr, 0, sizeof(arr))
const int inf = 0x3f3f3f3f;
class BigInteger { public:
int size,num[1000];
BigInteger()
{
size=0;
memset(num,0,sizeof(num));
}
BigInteger(int data)
{
size=0;
while (data!=0)
{
size++;
num[size]=data%10;
data=data/10;
}
}
void init(int data)
{
size=0;
while (data!=0)
{
size++;
num[size]=data%10;
data=data/10;
}
}
};
BigInteger operator + (BigInteger A,BigInteger B)
{
BigInteger Ans;
int s=max(A.size,B.size);
Ans.size=s;
for (int i=1;i<=s;i++)
Ans.num[i]=A.num[i]+B.num[i];
for (int i=1;i<=s;i++)
if (Ans.num[i]>=10)
{
Ans.num[i+1]+=Ans.num[i]/10;
Ans.num[i]=Ans.num[i]%10;
}
if (Ans.num[s+1]!=0)
Ans.size++;
return Ans;
}
BigInteger operator - (BigInteger A,BigInteger B)
{
BigInteger Ans;
int s=max(A.size,B.size);
Ans.size=s;
for (int i=1;i<=s;i++)
Ans.num[i]=A.num[i]-B.num[i];
for (int i=1;i<=s;i++)
if (Ans.num[i]<0)
{
Ans.num[i+1]-=Ans.num[i]/10;
Ans.num[i]=Ans.num[i]%10;
}
if (Ans.num[s+1]!=0)
Ans.size++;
return Ans;
}
ostream & operator << (ostream &os,BigInteger A)
{
int s=A.size;
for (int i=s;i>=1;i--)
os<<A.num[i];
return os;
}
BigInteger operator * (BigInteger A,BigInteger B)
{
BigInteger Ans;
int s1=A.size,s2=B.size;
for (int i=1;i<=s1;i++)
for (int j=1;j<=s2;j++)
Ans.num[i+j-1]+=A.num[i]*B.num[j];
int s=s1+s2-1;
int k=1;
while ((Ans.num[k]!=0)||(k<=s))
{
Ans.num[k+1]+=Ans.num[k]/10;
Ans.num[k]=Ans.num[k]%10;
k++;
}
if (Ans.num[k]==0)
k--;
Ans.size=k;
return Ans;
}
inline int read()
{
int x=0,c=1;
char ch=' ';
while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
while(ch=='-') c*=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
return x*c;
}
BigInteger f1,f2,f3,ans;
int main()
{
f1.init(1);
f2.init(3);
int n=read();
for(re int i=3;i<=n;i++)
f3=f1+f2,f1=f2,f2=f3;
if(n==1) f3=f1;
if(n==2) f3=f2;
ans=f3*f3-((n%2==0)?4:0);
cout<<ans;
return 0;
}