1002: [FJOI2007]轮状病毒
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5960 Solved: 3251
[Submit][Status][Discuss]
Description
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示
![](http://www.lydsy.com/JudgeOnline/upload/201604/1%283%29.png)
N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
同的3轮状病毒,如下图所示
![](http://www.lydsy.com/JudgeOnline/upload/201604/2%283%29.png)
现给定n(N<=100),编程计算有多少个不同的n轮状病毒
Input
第一行有1个正整数n
Output
计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
HINT
Source
第n项公式f[n]=f[n-1]*3-f[n-2]+2,高精度求即可
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct bignum{
int len;
int num[1000];
}ans[110],k;
inline bignum operator * (bignum x,int y){
bignum z;
memset(&z,0,sizeof(z));
for(int i=1;i<=x.len;i++){
z.num[i]+=x.num[i]*y;
z.num[i+1]=z.num[i+1]+z.num[i]/10;
z.num[i]%=10;
}
z.len=x.len;
if(z.num[x.len+1]) z.len++;
return z;
}
inline void operator += (bignum &x,bignum y){
bignum z;
memset(&z,0,sizeof(z));
z.len=max(x.len,y.len);
for(int i=1;i<=z.len;i++){
z.num[i]+=x.num[i]+y.num[i];
if(z.num[i]>=10) z.num[i]-=10,z.num[i+1]++;
}
if(z.num[z.len+1]) z.len++;
x=z;
}
inline void operator -= (bignum &x,bignum y){
bignum z;
memset(&z,0,sizeof(z));
for(int i=1;i<=x.len;i++){
z.num[i]+=x.num[i]-y.num[i];
if(z.num[i]<0) z.num[i+1]--,z.num[i]+=10;
}
if(!z.num[x.len]) z.len=x.len-1;
else z.len=x.len;
x=z;
}
void print(bignum x){
for(int i=x.len;i>=1;i--){
cout<<x.num[i];
}
cout<<endl;
}
int main(){
int n=read();
ans[1].len=1;ans[1].num[1]=1;ans[2].len=1;ans[2].num[1]=5;
for(int i=3;i<=n;i++){
ans[i].len=1;ans[i].num[1]=2;
ans[i]+=ans[i-1]*3;
ans[i]-=ans[i-2];
}
print(ans[n]);
return 0;
}