生成树的计数(基尔霍夫矩阵):BZOJ 1002 [FJOI2007]轮状病毒

1002: [FJOI2007]轮状病毒

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 3928  Solved: 2154
[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
  纯属娱乐~~~
  1 #ifndef EXTINT_H
  2 #define EXTINT_H
  3 
  4 #include <cctype>
  5 #include <string>
  6 #include <istream>
  7 #include <ostream>
  8 #include <cassert>
  9 #include <iomanip>
 10 #include <iostream>
 11 
 12 class ExtInt{
 13 friend ExtInt operator +(const ExtInt &a, const ExtInt &b);
 14 friend ExtInt operator -(const ExtInt &a, const ExtInt &b);
 15 friend ExtInt operator *(const ExtInt &a, const ExtInt &b);
 16 friend ExtInt operator /(const ExtInt &a, const ExtInt &b);
 17 friend ExtInt operator %(const ExtInt &a, const ExtInt &b);
 18 friend bool operator <(const ExtInt &a, const ExtInt &b);
 19 friend bool operator >(const ExtInt &a, const ExtInt &b);
 20 friend bool operator <=(const ExtInt &a, const ExtInt &b);
 21 friend bool operator >=(const ExtInt &a, const ExtInt &b);
 22 friend bool operator ==(const ExtInt &a, const ExtInt &b);
 23 friend bool operator !=(const ExtInt &a, const ExtInt &b);
 24 friend std::istream & operator >>(std::istream &inputStream, ExtInt &data);
 25 friend std::ostream & operator <<(std::ostream &outputStream, const ExtInt &data);
 26 private:
 27     static const int LIMIT = 1000000000;
 28     static const int WIDTH = 9;
 29     int length;
 30     bool isNegative;
 31     struct DListNode{
 32         int data;
 33         DListNode *forward, *next;
 34         DListNode(int data = 0) : data(data), forward(NULL), next(NULL) {}
 35         DListNode & remove();
 36         DListNode & append(DListNode *data);
 37         DListNode & append(const int &data);
 38         DListNode & insert(DListNode *data);
 39         DListNode & insert(const int &data);
 40     }*low, *high;
 41 public:
 42     ExtInt(int data = 0);
 43     ExtInt(const ExtInt &rhs);
 44     ExtInt(const std::string &rhs);
 45     virtual ~ExtInt();
 46     
 47     ExtInt & operator =(const ExtInt &rhs);
 48     ExtInt & operator +=(const ExtInt &rhs);
 49     ExtInt & operator -=(const ExtInt &rhs);
 50     ExtInt & operator *=(const ExtInt &rhs);
 51     ExtInt & operator /=(const ExtInt &rhs);
 52     ExtInt & operator %=(const ExtInt &rhs);
 53     //ExtInt & operator ++();
 54     //ExtInt & operator ++(int);
 55     //ExtInt & operator --();
 56     //ExtInt & operator --(int);
 57 };
 58 
 59 
 60 #endif
 61 
 62 
 63 ExtInt::DListNode & ExtInt::DListNode::remove() {
 64     DListNode *tmp = this -> forward;
 65     tmp -> forward -> next = this;
 66     this -> forward = tmp -> forward;
 67     delete tmp;
 68     return *this;
 69 }
 70 ExtInt::DListNode & ExtInt::DListNode::append(DListNode *data) {
 71     data -> next = this -> next;
 72     data -> forward = this;
 73     if (this -> next != NULL) {
 74         this -> next -> forward = data;
 75     }
 76     this -> next = data;
 77     return *this;
 78 }
 79 ExtInt::DListNode & ExtInt::DListNode::append(const int &data) {
 80     return append(new DListNode(data));
 81 }
 82 ExtInt::DListNode & ExtInt::DListNode::insert(DListNode *data) {
 83     data -> next = this;
 84     data -> forward = this -> forward;
 85     if (this -> forward != NULL) {
 86         this -> forward -> next = data;
 87     }
 88     this -> forward = data;
 89     return *this;
 90 }
 91 ExtInt::DListNode & ExtInt::DListNode::insert(const int &data) {
 92     return insert(new DListNode(data));
 93 }
 94 
 95 ExtInt::ExtInt(int data) {
 96     low = new DListNode;
 97     high = new DListNode;
 98     low -> append(high);
 99     length = 0;
100     isNegative = false;
101     if (data < 0) {
102         isNegative = true;
103         data = -data;
104     }
105     while (data >= ExtInt::LIMIT) {
106         high -> insert(data % ExtInt::LIMIT);
107         data /= ExtInt::LIMIT;
108         length++;
109     }
110     if (length == 0 || data > 0) {
111         high -> insert(data);
112         length++;
113     }
114 }
115 ExtInt::ExtInt(const ExtInt &rhs) {
116     low = new DListNode;
117     high = new DListNode;
118     low -> append(high);
119     length = 0;
120     isNegative = rhs.isNegative;
121     for (DListNode *it = rhs.low -> next; it != rhs.high; it = it -> next) {
122         high -> insert(it -> data);
123         length++;
124     }
125 }
126 ExtInt::ExtInt(const std::string &rhs) {
127     low = new DListNode;
128     high = new DListNode;
129     low -> append(high);
130     length = 0;
131     isNegative = false;
132     if (rhs[0] == '-') {
133         isNegative = true;
134     }
135     for (int i = rhs.length() - 1; i >= 0; i -= WIDTH) {
136         int value = 0;
137         for (int j = std::max(0, i - WIDTH + 1); j <= i; j++) {
138             if (j == 0 && isNegative) continue;
139             assert(isdigit(rhs[j]));
140             value = value * 10 + rhs[j] - '0';
141         }
142         high -> insert(value);
143         length++;
144     }
145     while (length > 1 && high -> forward -> data == 0) {
146         high -> remove();
147         length--;
148     }
149 }
150 ExtInt & ExtInt::operator =(const ExtInt &rhs) {
151     if (this == &rhs) return *this;
152     if (low != NULL || high != NULL) {
153         this -> ~ExtInt();
154     }
155     low = new DListNode;
156     high = new DListNode;
157     low -> append(high);
158     length = 0;
159     isNegative = rhs.isNegative;
160     for (DListNode *it = rhs.low -> next; it != rhs.high; it = it -> next) {
161         high -> insert(it -> data);
162         length++;
163     }
164     return *this;
165 }
166 ExtInt::~ExtInt() {
167     for (DListNode *it = low; it != NULL;) {
168         DListNode *tmp = it -> next;
169         delete it;
170         it = tmp;
171     }
172 }
173 
174 std::istream & operator >>(std::istream &inputStream, ExtInt &data) {
175     std::string tmp;
176     inputStream >> tmp;
177     data = ExtInt(tmp);
178     return inputStream;
179 }
180 std::ostream & operator <<(std::ostream &outputStream, const ExtInt &data) {
181     if (data.isNegative) {
182         outputStream << "-";
183     }
184     ExtInt::DListNode *it = data.high -> forward;
185     outputStream << it -> data;
186     for (it = it -> forward; it != data.low; it = it -> forward) {
187         outputStream << std::setfill('0') << std::setw(ExtInt::WIDTH) << it -> data;
188     }
189     return outputStream;
190 }
191 
192 bool operator <(const ExtInt &a, const ExtInt &b) {
193     if (a.isNegative && !b.isNegative) return true;
194     if (!a.isNegative && b.isNegative) return false;
195     bool flag = false;
196     if (a.isNegative && b.isNegative) flag = true;
197     if (a.length < b.length) return flag ^ true;
198     if (a.length > b.length) return flag ^ false;
199     ExtInt::DListNode *itA = a.high, *itB = b.high;
200     for (; itA != a.low && itB != b.low; itA = itA -> forward, itB = itB -> forward) {
201         if (itA -> data < itB -> data) return flag ^ true;
202         if (itA -> data > itB -> data) return flag ^ false;
203     }
204     return false;
205 }
206 bool operator >(const ExtInt &a, const ExtInt &b) {
207     if (a.isNegative && !b.isNegative) return false;
208     if (!a.isNegative && b.isNegative) return true;
209     bool flag = false;
210     if (a.isNegative && b.isNegative) flag = true;
211     if (a.length < b.length) return flag ^ false;
212     if (a.length > b.length) return flag ^ true;
213     ExtInt::DListNode *itA = a.high, *itB = b.high;
214     for (; itA != a.low && itB != b.low; itA = itA -> forward, itB = itB -> forward) {
215         if (itA -> data < itB -> data) return flag ^ false;
216         if (itA -> data > itB -> data) return flag ^ true;
217     }
218     return false;
219 }
220 bool operator >=(const ExtInt &a, const ExtInt &b) {
221     return !(a < b);
222 }
223 bool operator <=(const ExtInt &a, const ExtInt &b) {
224     return !(a > b);
225 }
226 bool operator ==(const ExtInt &a, const ExtInt &b) {
227     if (a.isNegative != b.isNegative) return false;
228     if (a.length != b.length) return false;
229     ExtInt::DListNode *itA = a.low, *itB = b.low;
230     for (; itA != a.high && itB != b.high; itA = itA -> next, itB = itB -> next) {
231         if (itA -> data != itB -> data) return false;
232     }
233     return true;
234 }
235 bool operator !=(const ExtInt &a, const ExtInt &b) {
236     return !(a == b);
237 }
238 
239 ExtInt operator +(const ExtInt &a, const ExtInt &b) {
240     if (b.isNegative) {
241         ExtInt tmp = b;
242         tmp.isNegative = false;
243         return a - tmp;
244     }
245     if (a.isNegative) {
246         ExtInt tmp = a;
247         tmp.isNegative = false;
248         return b - tmp;
249     }
250     ExtInt ret = a;
251     ExtInt::DListNode *itA = ret.low -> next, *itB = b.low -> next;
252     for (; itB != b.high; itA = itA -> next, itB = itB -> next) {
253         if (itA == ret.high) {
254             itA -> insert(0);
255             ret.length++;
256             itA = itA -> forward;
257         }
258         itA -> data += itB -> data;
259         if (itA -> data >= ExtInt::LIMIT) {
260             if (itA -> next == ret.high) {
261                 itA -> append(0);
262                 ret.length++;
263             }
264             itA -> next -> data += itA -> data / ExtInt::LIMIT;
265             itA -> data %= ExtInt::LIMIT;
266         }
267     }
268     return ret;
269 }
270 ExtInt operator -(const ExtInt &a, const ExtInt &b) {
271     if (b.isNegative) {
272         ExtInt tmp = b;
273         tmp.isNegative = false;
274         return a + tmp;
275     }
276     if (a.isNegative) {
277         ExtInt tmp = a;
278         tmp.isNegative = false;
279         tmp = tmp + b;
280         tmp.isNegative = true;
281         return tmp;
282     }
283     if (a < b) {
284         ExtInt tmp = b - a;
285         tmp.isNegative = true;
286         return tmp;
287     }
288     ExtInt ret = a;
289     ExtInt::DListNode *itA = ret.low -> next, *itB = b.low -> next;
290     for (; itA != ret.high && itB != b.high; itA = itA -> next, itB = itB -> next) {
291         itA -> data -= itB -> data;
292         if (itA -> data < 0) {
293             itA -> data += ExtInt::LIMIT;
294             itA -> next -> data--;
295         }
296     }
297     for (; itA != ret.high; itA = itA -> next) {
298         if (itA -> data < 0) {
299             itA -> data += ExtInt::LIMIT;
300             itA -> next -> data--;
301         }
302     }
303     while (ret.length > 1 && ret.high -> forward -> data == 0) {
304         ret.high -> remove();
305         ret.length--;
306     }
307     return ret;
308 }
309 ExtInt operator *(const ExtInt &a, const ExtInt &b) {
310     if (a == ExtInt(0) || b == ExtInt(0)) return ExtInt(0);
311     ExtInt ret, tmp;
312     ExtInt::DListNode *itB = b.low -> next;
313     for (int value = 0; itB != b.high; itB = itB -> next, value++) {
314         if (itB -> data == 0) {
315             continue;
316         }
317         tmp = a;
318         ExtInt::DListNode *itA = tmp.low -> next;
319         for (long long r = 0; itA != tmp.high; itA = itA -> next) {
320             long long now = 1ll * itA -> data * itB -> data + r;
321             itA -> data = now % ExtInt::LIMIT;
322             r = 0;
323             if (now >= ExtInt::LIMIT) {
324                 if (itA -> next == tmp.high) {
325                     itA -> append(0);
326                     tmp.length++;
327                 }
328                 r = now / ExtInt::LIMIT;
329             }
330         }
331         for (int i = 1; i <= value; i++) {
332             tmp.low -> append(0);
333             tmp.length++;
334         }
335         //std::cerr << ret << std::endl;
336         //std::cerr << tmp << std::endl;
337         //std::cerr << tmp.length << std::endl;
338         ret = ret + tmp;
339     }
340     ret.isNegative = a.isNegative ^ b.isNegative;
341     return ret;
342 }
343 ExtInt operator /(const ExtInt &a, const ExtInt &b) {
344     assert(b != ExtInt(0));
345     if (a == ExtInt(0)) return ExtInt(0);
346     ExtInt ret, tmp, div = b;
347     ret.high -> remove();
348     ret.length = 0;
349     tmp.high -> remove();
350     tmp.length = 0;
351     div.isNegative = false;
352     ExtInt::DListNode *itA = a.high -> forward;
353     for (; itA != a.low; itA = itA -> forward) {
354         tmp.low -> append(itA -> data);
355         tmp.length++;
356         if (tmp >= div) {
357             int left = 0, right = ExtInt::LIMIT - 1;
358             while (left < right) {
359                 int middle = (left + right >> 1) + 1;
360                 if (tmp >= div * middle) {
361                     left = middle;
362                 } else {
363                     right = middle - 1;
364                 }
365             }
366             //std::cerr << tmp << " " << div * left << std::endl;
367             ret.low -> append(left);
368             ret.length++;
369             tmp = tmp - div * left;
370         } else {
371             ret.low -> append(0);
372             ret.length++;
373         }
374         if (tmp == ExtInt(0)) {
375             tmp.high -> remove();
376             tmp.length = 0;
377         }
378     }
379     while (ret.length > 1 && ret.high -> forward -> data == 0) {
380         ret.high -> remove();
381         ret.length--;
382     }
383     ret.isNegative = a.isNegative ^ b.isNegative;
384     if (ret.isNegative && tmp.low -> next != tmp.high) {
385         ret = ret - 1;
386     }
387     return ret;
388 }
389 ExtInt operator %(const ExtInt &a, const ExtInt &b) {
390     return a - a / b * b;
391 }
392 
393 ExtInt & ExtInt::operator +=(const ExtInt &rhs) {
394     *this = *this + rhs;
395     return *this;
396 }
397 ExtInt & ExtInt::operator -=(const ExtInt &rhs) {
398     *this = *this - rhs;
399     return *this;
400 }
401 ExtInt & ExtInt::operator *=(const ExtInt &rhs) {
402     *this = *this * rhs;
403     return *this;
404 }
405 ExtInt & ExtInt::operator /=(const ExtInt &rhs) {
406     *this = *this / rhs;
407     return *this;
408 }
409 ExtInt & ExtInt::operator %=(const ExtInt &rhs) {
410     *this = *this % rhs;
411     return *this;
412 }
413 #include <iostream>
414 #include <cstdio>
415 using namespace std;
416 int n;
417 const int maxn=110;
418 ExtInt C[maxn][maxn]; 
419 void abs(ExtInt &x){
420     if(x<0)x=x*(-1);
421 }
422 void Solve(){
423     for(int i=1;i<n;i++){
424         for(int j=i+1;j<n;j++)
425             while(C[j][i]!=0){
426                 ExtInt r=C[i][i]/C[j][i];
427                 for(int k=i;k<n;k++)
428                     C[i][k]-=C[j][k]*r;
429                 swap(C[i],C[j]);    
430             }    
431     }
432     ExtInt ans=1; 
433     for(int i=1;i<n;i++)
434         ans*=C[i][i];
435     abs(ans);    
436     cout<<ans<<endl;        
437     return;    
438 }
439 int main(){
440     scanf("%d",&n);n++;
441     if(n!=2)
442     for(int i=1;i<n;i++){
443         C[i][i%(n-1)+1]-=1;
444         C[i%(n-1)+1][i]-=1;C[i][i]+=1;
445         C[i%(n-1)+1][i%(n-1)+1]+=1;
446     }
447     for(int i=1;i<n;i++){
448         C[i][n]=-1;
449         C[n][i]=-1;
450         C[i][i]+=1;
451         C[n][n]+=1;
452     }
453     Solve();
454     return 0;
455 }

 

posted @ 2016-04-17 18:01  TenderRun  阅读(477)  评论(0编辑  收藏  举报