首页 > 代码库 > [bzoj1002][FJOI2007 轮状病毒] (生成树计数+递推+高精度)

[bzoj1002][FJOI2007 轮状病毒] (生成树计数+递推+高精度)

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

#include<stdio.h>#include<string.h>struct big{    int x[110],ln;}f[110];big sub(big a,big b){    big c=a;    c.x[1]+=2;    for(int i=1;i<=c.ln;i++){        c.x[i]-=b.x[i];        if(c.x[i]<0)            c.x[i]+=10,            c.x[i+1]--;    }    while(!c.x[c.ln])c.ln--;    return c;}big mul(big a){    big c=a;    for(int i=1;i<=c.ln;i++)        c.x[i]*=3;    for(int i=1;i<=c.ln;i++)        c.x[i+1]+=c.x[i]/10,        c.x[i]%=10;    while(c.x[c.ln+1])c.ln++;    return c;}int n;int main(){    scanf("%d",&n);    f[1].x[1]=f[1].ln=1;    f[2].x[1]=5;f[2].ln=1;    for(int i=3;i<=n;i++)        f[i]=sub(mul(f[i-1]),f[i-2]);    for(int i=f[n].ln;i;i--)        printf("%d",f[n].x[i]);    putchar(\n);    return 0;}

 

[bzoj1002][FJOI2007 轮状病毒] (生成树计数+递推+高精度)