1. 程式人生 > >1002. [FJOI2007]輪狀病毒【找規律+遞推】

1002. [FJOI2007]輪狀病毒【找規律+遞推】

stream istream tdi data urn 打表 pan www void

Description

  輪狀病毒有很多變種,所有輪狀病毒的變種都是從一個輪狀基產生的。一個N輪狀基由圓環上N個不同的基原子
和圓心處一個核原子構成的,2個原子之間的邊表示這2個原子之間的信息通道。如下圖所示

技術分享圖片

  N輪狀病毒的產生規律是在一個N輪狀基中刪去若幹條邊,使得各原子之間有唯一的信息通道,例如共有16個不
同的3輪狀病毒,如下圖所示

技術分享圖片   現給定n(N<=100),編程計算有多少個不同的n輪狀病毒

Input

  第一行有1個正整數n

Output

  計算出的不同的n輪狀病毒數輸出

Sample Input

3

Sample Output

16 數論推個P,打表找規律
emmm聽說這個題要用矩陣樹定理……我不會啊……
然後我就去找題解想學一下……然後就看到了一篇找規律的題解……
f[1]=1,f[2]=3,答案就是斐波那契數列的第n項的平方,如果n是偶數還要再減4
高精度都懶得打了……直接搬了一個
啥?矩陣樹?以後再說吧
  1 #include <iostream>
  2 #include <cstdio>
  3
#include <cstdlib> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 using namespace std; 8 9 const int MAXN = 410; 10 11 struct bign 12 { 13 int len, s[MAXN]; 14 bign () 15 { 16 memset(s, 0, sizeof(s)); 17
len = 1; 18 } 19 bign (int num) { *this = num; } 20 bign (const char *num) { *this = num; } 21 bign operator = (const int num) 22 { 23 char s[MAXN]; 24 sprintf(s, "%d", num); 25 *this = s; 26 return *this; 27 } 28 bign operator = (const char *num) 29 { 30 for(int i = 0; num[i] == 0; num++) ; //去前導0 31 len = strlen(num); 32 for(int i = 0; i < len; i++) s[i] = num[len-i-1] - 0; 33 return *this; 34 } 35 bign operator + (const bign &b) const //+ 36 { 37 bign c; 38 c.len = 0; 39 for(int i = 0, g = 0; g || i < max(len, b.len); i++) 40 { 41 int x = g; 42 if(i < len) x += s[i]; 43 if(i < b.len) x += b.s[i]; 44 c.s[c.len++] = x % 10; 45 g = x / 10; 46 } 47 return c; 48 } 49 bign operator += (const bign &b) 50 { 51 *this = *this + b; 52 return *this; 53 } 54 void clean() 55 { 56 while(len > 1 && !s[len-1]) len--; 57 } 58 bign operator * (const bign &b) //* 59 { 60 bign c; 61 c.len = len + b.len; 62 for(int i = 0; i < len; i++) 63 { 64 for(int j = 0; j < b.len; j++) 65 { 66 c.s[i+j] += s[i] * b.s[j]; 67 } 68 } 69 for(int i = 0; i < c.len; i++) 70 { 71 c.s[i+1] += c.s[i]/10; 72 c.s[i] %= 10; 73 } 74 c.clean(); 75 return c; 76 } 77 bign operator *= (const bign &b) 78 { 79 *this = *this * b; 80 return *this; 81 } 82 bign operator - (const bign &b) 83 { 84 bign c; 85 c.len = 0; 86 for(int i = 0, g = 0; i < len; i++) 87 { 88 int x = s[i] - g; 89 if(i < b.len) x -= b.s[i]; 90 if(x >= 0) g = 0; 91 else 92 { 93 g = 1; 94 x += 10; 95 } 96 c.s[c.len++] = x; 97 } 98 c.clean(); 99 return c; 100 } 101 bign operator -= (const bign &b) 102 { 103 *this = *this - b; 104 return *this; 105 } 106 bign operator / (const bign &b) 107 { 108 bign c, f = 0; 109 for(int i = len-1; i >= 0; i--) 110 { 111 f = f*10; 112 f.s[0] = s[i]; 113 while(f >= b) 114 { 115 f -= b; 116 c.s[i]++; 117 } 118 } 119 c.len = len; 120 c.clean(); 121 return c; 122 } 123 bign operator /= (const bign &b) 124 { 125 *this = *this / b; 126 return *this; 127 } 128 bign operator % (const bign &b) 129 { 130 bign r = *this / b; 131 r = *this - r*b; 132 return r; 133 } 134 bign operator %= (const bign &b) 135 { 136 *this = *this % b; 137 return *this; 138 } 139 bool operator < (const bign &b) 140 { 141 if(len != b.len) return len < b.len; 142 for(int i = len-1; i >= 0; i--) 143 { 144 if(s[i] != b.s[i]) return s[i] < b.s[i]; 145 } 146 return false; 147 } 148 bool operator > (const bign &b) 149 { 150 if(len != b.len) return len > b.len; 151 for(int i = len-1; i >= 0; i--) 152 { 153 if(s[i] != b.s[i]) return s[i] > b.s[i]; 154 } 155 return false; 156 } 157 bool operator == (const bign &b) 158 { 159 return !(*this > b) && !(*this < b); 160 } 161 bool operator != (const bign &b) 162 { 163 return !(*this == b); 164 } 165 bool operator <= (const bign &b) 166 { 167 return *this < b || *this == b; 168 } 169 bool operator >= (const bign &b) 170 { 171 return *this > b || *this == b; 172 } 173 string str() const 174 { 175 string res = ""; 176 for(int i = 0; i < len; i++) res = char(s[i]+0) + res; 177 return res; 178 } 179 }; 180 181 istream& operator >> (istream &in, bign &x) 182 { 183 string s; 184 in >> s; 185 x = s.c_str(); 186 return in; 187 } 188 189 ostream& operator << (ostream &out, const bign &x) 190 { 191 out << x.str(); 192 return out; 193 } 194 195 bign a,b; 196 int n; 197 198 int main() 199 { 200 scanf("%d",&n); 201 if (n==1){printf("1"); return 0;} 202 if (n==2){printf("5"); return 0;} 203 a=1,b=3; 204 for (int i=3;i<=n;++i) 205 { 206 a=a+b; 207 swap(a,b); 208 } 209 if (n%2==1) b=b*b; 210 else b=b*b-4; 211 cout<<b; 212 }

1002. [FJOI2007]輪狀病毒【找規律+遞推】