bzoj - 1002 【Kirchhoff矩阵】

1002: [FJOI2007]轮状病毒

Time Limit: 1 Sec   Memory Limit: 162 MB
Submit: 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 }  
View Code

 

转载于:https://www.cnblogs.com/Jstyle-continue/p/6351924.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值