1002: [FJOI2007]轮状病毒
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4746 Solved: 2597
[Submit][Status][Discuss]
Description
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示

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

现给定n(N<=100),编程计算有多少个不同的n轮状病毒
Input
第一行有1个正整数n
Output
计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
学习:2007周冬《生成树计数》 论文
题解:推公式,f[n] = 3*f[n-1] - f[n-2] + 2。高精度模拟
代码:

1 /************************************************************** 2 Problem: 1002 3 User: Jstyle 4 Language: C++ 5 Result: Accepted 6 Time:44 ms 7 Memory:1456 kb 8 ****************************************************************/ 9 10 #include <iostream> 11 #include <algorithm> 12 #include <cstring> 13 #include <cstdio> 14 #include <bitset> 15 #include <vector> 16 #include <queue> 17 #include <stack> 18 #include <cmath> 19 #include <list> 20 #include <set> 21 #include <map> 22 #define rep(i,a,b) for(int (i) = (a);(i) <= (b);++ (i)) 23 #define per(i,a,b) for(int (i) = (a);(i) >= (b);-- (i)) 24 #define mem(a,b) memset((a),(b),sizeof((a))) 25 #define FIN freopen("in.txt","r",stdin) 26 #define FOUT freopen("out.txt","w",stdout) 27 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 28 #define mid ((l+r)>>1) 29 #define ls (id<<1) 30 #define rs ((id<<1)|1) 31 #define N 100000+5 32 #define INF 0x3f3f3f3f 33 #define INFF 0x3f3f3f3f3f3f3f 34 typedef long long ll; 35 const ll mod = 20071027; 36 const ll eps = 1e-12; 37 using namespace std; 38 39 const int MAXN = 410; 40 41 struct bign 42 { 43 int len, s[MAXN]; 44 bign () 45 { 46 memset(s, 0, sizeof(s)); 47 len = 1; 48 } 49 bign (int num) { *this = num; } 50 bign (const char *num) { *this = num; } 51 bign operator = (const int num) 52 { 53 char s[MAXN]; 54 sprintf(s, "%d", num); 55 *this = s; 56 return *this; 57 } 58 bign operator = (const char *num) 59 { 60 for(int i = 0; num[i] == '0'; num++) ; //去前导0 61 len = strlen(num); 62 for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0'; 63 return *this; 64 } 65 bign operator + (const bign &b) const //+ 66 { 67 bign c; 68 c.len = 0; 69 for(int i = 0, g = 0; g || i < max(len, b.len); i++) 70 { 71 int x = g; 72 if(i < len) x += s[i]; 73 if(i < b.len) x += b.s[i]; 74 c.s[c.len++] = x % 10; 75 g = x / 10; 76 } 77 return c; 78 } 79 bign operator += (const bign &b) 80 { 81 *this = *this + b; 82 return *this; 83 } 84 void clean() 85 { 86 while(len > 1 && !s[len-1]) len--; 87 } 88 bign operator * (const bign &b) //* 89 { 90 bign c; 91 c.len = len + b.len; 92 for(int i = 0; i < len; i++) 93 { 94 for(int j = 0; j < b.len; j++) 95 { 96 c.s[i+j] += s[i] * b.s[j]; 97 } 98 } 99 for(int i = 0; i < c.len; i++) 100 { 101 c.s[i+1] += c.s[i]/10; 102 c.s[i] %= 10; 103 } 104 c.clean(); 105 return c; 106 } 107 bign operator *= (const bign &b) 108 { 109 *this = *this * b; 110 return *this; 111 } 112 bign operator - (const bign &b) 113 { 114 bign c; 115 c.len = 0; 116 for(int i = 0, g = 0; i < len; i++) 117 { 118 int x = s[i] - g; 119 if(i < b.len) x -= b.s[i]; 120 if(x >= 0) g = 0; 121 else 122 { 123 g = 1; 124 x += 10; 125 } 126 c.s[c.len++] = x; 127 } 128 c.clean(); 129 return c; 130 } 131 bign operator -= (const bign &b) 132 { 133 *this = *this - b; 134 return *this; 135 } 136 bign operator / (const bign &b) 137 { 138 bign c, f = 0; 139 for(int i = len-1; i >= 0; i--) 140 { 141 f = f*10; 142 f.s[0] = s[i]; 143 while(f >= b) 144 { 145 f -= b; 146 c.s[i]++; 147 } 148 } 149 c.len = len; 150 c.clean(); 151 return c; 152 } 153 bign operator /= (const bign &b) 154 { 155 *this = *this / b; 156 return *this; 157 } 158 bign operator % (const bign &b) 159 { 160 bign r = *this / b; 161 r = *this - r*b; 162 return r; 163 } 164 bign operator %= (const bign &b) 165 { 166 *this = *this % b; 167 return *this; 168 } 169 bool operator < (const bign &b) 170 { 171 if(len != b.len) return len < b.len; 172 for(int i = len-1; i >= 0; i--) 173 { 174 if(s[i] != b.s[i]) return s[i] < b.s[i]; 175 } 176 return false; 177 } 178 bool operator > (const bign &b) 179 { 180 if(len != b.len) return len > b.len; 181 for(int i = len-1; i >= 0; i--) 182 { 183 if(s[i] != b.s[i]) return s[i] > b.s[i]; 184 } 185 return false; 186 } 187 bool operator == (const bign &b) 188 { 189 return !(*this > b) && !(*this < b); 190 } 191 bool operator != (const bign &b) 192 { 193 return !(*this == b); 194 } 195 bool operator <= (const bign &b) 196 { 197 return *this < b || *this == b; 198 } 199 bool operator >= (const bign &b) 200 { 201 return *this > b || *this == b; 202 } 203 string str() const 204 { 205 string res = ""; 206 for(int i = 0; i < len; i++) res = char(s[i]+'0') + res; 207 return res; 208 } 209 }; 210 211 istream& operator >> (istream &in, bign &x) 212 { 213 string s; 214 in >> s; 215 x = s.c_str(); 216 return in; 217 } 218 219 ostream& operator << (ostream &out, const bign &x) 220 { 221 out << x.str(); 222 return out; 223 } 224 225 int n; 226 bign dp[105]; 227 void fuc(){ 228 bign a = "3",b = "2"; 229 dp[1] = "1"; 230 dp[2] = "5"; 231 rep(i, 3, 100) 232 dp[i] = a*dp[i-1]-dp[i-2]+b; 233 } 234 int main() 235 { 236 fuc(); 237 while(cin >> n) 238 cout << dp[n] << endl; 239 return 0; 240 }