zoukankan      html  css  js  c++  java
  • 生成树的计数(基尔霍夫矩阵):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 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    C语言指向指针的指针
    C语言注意事项
    C语言指针
    C语言字符串
    C语言数组
    C语言交换两个数的值
    C语言位运算符
    C语言各种进制输出
    C语言中各种进制的表示
    C 语言sizeof运算符
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5401669.html
Copyright © 2011-2022 走看看