[FJOI2007]轮状病毒

Description

  轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示

img

  N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
同的3轮状病毒,如下图所示

img

  现给定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;
}
posted @ 2018-06-12 16:00  ~victorique~  阅读(196)  评论(0编辑  收藏  举报
Live2D