正解:貌似有个叫基尔霍夫矩阵的东西???反正我不会
非正解:打表找规律(要真是省选,打30分钟的表可以A一道题还是很值的对吧)
我们要求一个。。。有N+1个节点的2*N条边的图的生成树的个数,N<=100,那就先打个爆搜?应该有30分吧
1 #pragma GCC optimize(2) 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #define int __int128 7 using namespace std; 8 inline int read(){ 9 char chr=getchar(); int f=1,ans=0; 10 while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();} 11 while(isdigit(chr)) {ans=(ans<<3)+(ans<<1);ans+=chr-'0';chr=getchar();} 12 return ans*f; 13 }void write(int x){ 14 if(x<0) putchar('-'),x=-x; 15 if(x>9) write(x/10); 16 putchar(x%10+'0'); 17 }int n,fa[105],ans,tot; 18 int find(int x){if(fa[x]==x) return x;return find(fa[x]);}//要删除 19 struct P{int x,y;}edge[10001]; 20 void dfs(int x,int now){//当前的搜索的边数(x) 已经加入图的边数(now) 21 if(tot-x+1<n-now-1) return;//可行性剪枝,如果把剩下所有的边都加进去都没有一棵树,则不可能 22 if(now==n-1) {++ans;return;} 23 dfs(x+1,now);//01搜索,选这条边 24 int fx=find(edge[x].x),fy=find(edge[x].y);//不选这条边 25 if(fx!=fy){int t=fa[fx]; //显然这里的并查集是要支持删除操作的,不用想太多,不要路径压缩即可 26 fa[fx]=fy; 27 dfs(x+1,now+1); 28 fa[fx]=t;//删除一次操作,把father变成原来的father(儿子懂没?) 29 } 30 }int f[5005]; 31 signed main(){ 32 int T=read(); 33 for(int kk=1;kk<=T;kk++){ 34 n=kk;ans=0;tot=0; 35 for(int i=1;i<=n+10;i++) fa[i]=i; 36 for(int i=1;i<=n-1;i++) edge[++tot]={i,i+1};edge[++tot]={1,n}; 37 for(int i=1;i<=n;i++) edge[++tot]={n+1,i};++n;//建图加边 38 dfs(1,0);write(ans);puts("");//搜索输出答案 39 } 40 return 0; 41 }
让我们来看看它输出了啥:
1
5
16
45
121
320
841
2205
5776
15125
39601
103680
271441
710645
1860496
4870845
12752041
33385280
不难发现 ,n为奇数是,答案是完全平方数,那我们把它们开方出来(只列奇数项)
1
4
11
29
76
199
……
跟斐波那契数列有关,自己思考一下,不懂可以看代码
要高精:
1 #include <deque> 2 #include <vector> 3 #include <iostream> 4 #include <string> 5 #include <algorithm> 6 using namespace std; 7 8 class DividedByZeroException {}; 9 10 class BigInteger 11 { 12 private: 13 vector<char> digits; 14 bool sign; // true for positive, false for negitive 15 void trim(); // remove zeros in tail, but if the value is 0, keep only one:) 16 public: 17 BigInteger(int); // construct with a int integer 18 BigInteger(string&) ; 19 BigInteger(); 20 BigInteger (const BigInteger&); 21 BigInteger operator=(const BigInteger& op2); 22 23 BigInteger abs() const; 24 BigInteger pow(int a); 25 26 //binary operators 27 28 friend BigInteger operator+=(BigInteger&,const BigInteger&); 29 friend BigInteger operator-=(BigInteger&,const BigInteger&); 30 friend BigInteger operator*=(BigInteger&,const BigInteger&); 31 friend BigInteger operator/=(BigInteger&,const BigInteger&) throw(DividedByZeroException); 32 friend BigInteger operator%=(BigInteger&,const BigInteger&) throw(DividedByZeroException); 33 34 friend BigInteger operator+(const BigInteger&,const BigInteger&); 35 friend BigInteger operator-(const BigInteger&,const BigInteger&); 36 friend BigInteger operator*(const BigInteger&,const BigInteger&); 37 friend BigInteger operator/(const BigInteger&,const BigInteger&) throw(DividedByZeroException); 38 friend BigInteger operator%(const BigInteger&,const BigInteger&) throw(DividedByZeroException); 39 40 41 //uniary operators 42 friend BigInteger operator-(const BigInteger&); //negative 43 44 friend BigInteger operator++(BigInteger&); //++v 45 friend BigInteger operator++(BigInteger&,int); //v++ 46 friend BigInteger operator--(BigInteger&); //--v 47 friend BigInteger operator--(BigInteger&,int); //v-- 48 49 friend bool operator>(const BigInteger&,const BigInteger&); 50 friend bool operator<(const BigInteger&,const BigInteger&); 51 friend bool operator==(const BigInteger&,const BigInteger&); 52 friend bool operator!=(const BigInteger&,const BigInteger&); 53 friend bool operator>=(const BigInteger&,const BigInteger&); 54 friend bool operator<=(const BigInteger&,const BigInteger&); 55 56 friend ostream& operator<<(ostream&,const BigInteger&); //print the BigInteger 57 friend istream& operator>>(istream&, BigInteger&); // input the BigInteger 58 59 public: 60 static const BigInteger ZERO; 61 static const BigInteger ONE; 62 static const BigInteger TEN; 63 }; 64 // BigInteger.cpp 65 66 const BigInteger BigInteger::ZERO=BigInteger(0); 67 const BigInteger BigInteger::ONE =BigInteger(1); 68 const BigInteger BigInteger::TEN =BigInteger(10); 69 70 71 BigInteger::BigInteger() 72 { 73 sign=true; 74 } 75 76 77 BigInteger::BigInteger(int val){// construct with a int integer 78 if (val >= 0) 79 sign = true; 80 else{ 81 sign = false; 82 val *= (-1); 83 } 84 do{ 85 digits.push_back( (char)(val%10) ); 86 val /= 10; 87 } while ( val != 0 ); 88 } 89 90 91 BigInteger::BigInteger(string& def){ 92 sign=true; 93 for ( string::reverse_iterator iter = def.rbegin() ; iter < def.rend(); iter++){ 94 char ch = (*iter); 95 if (iter == def.rend()-1){ 96 if ( ch == '+' ) 97 break; 98 if(ch == '-' ){ 99 sign = false; 100 break; 101 } 102 } 103 digits.push_back( (char)((*iter) - '0' ) ); 104 } 105 trim(); 106 } 107 108 void BigInteger::trim(){ 109 vector<char>::reverse_iterator iter = digits.rbegin(); 110 while(!digits.empty() && (*iter) == 0){ 111 digits.pop_back(); 112 iter=digits.rbegin(); 113 } 114 if( digits.size()==0 ){ 115 sign = true; 116 digits.push_back(0); 117 } 118 } 119 120 121 BigInteger::BigInteger(const BigInteger& op2){ 122 sign = op2.sign; 123 digits=op2.digits; 124 } 125 126 127 BigInteger BigInteger::operator=(const BigInteger& op2){ 128 digits = op2.digits; 129 sign = op2.sign; 130 return (*this); 131 } 132 133 134 BigInteger BigInteger::abs() const { 135 if(sign) return *this; 136 else return -(*this); 137 } 138 139 BigInteger BigInteger::pow(int a) 140 { 141 BigInteger res(1); 142 for(int i=0; i<a; i++) 143 res*=(*this); 144 return res; 145 } 146 147 //binary operators 148 BigInteger operator+=(BigInteger& op1,const BigInteger& op2){ 149 if( op1.sign == op2.sign ){ //???????????,??????-?? 150 vector<char>::iterator iter1; 151 vector<char>::const_iterator iter2; 152 iter1 = op1.digits.begin(); 153 iter2 = op2.digits.begin(); 154 char to_add = 0; //?? 155 while ( iter1 != op1.digits.end() && iter2 != op2.digits.end()){ 156 (*iter1) = (*iter1) + (*iter2) + to_add; 157 to_add = ((*iter1) > 9); // ??9??? 158 (*iter1) = (*iter1) % 10; 159 iter1++; iter2++; 160 } 161 while ( iter1 != op1.digits.end() ){ // 162 (*iter1) = (*iter1) + to_add; 163 to_add = ( (*iter1) > 9 ); 164 (*iter1) %= 10; 165 iter1++; 166 } 167 while ( iter2 != op2.digits.end() ){ 168 char val = (*iter2) + to_add; 169 to_add = (val > 9) ; 170 val %= 10; 171 op1.digits.push_back(val); 172 iter2++; 173 } 174 if( to_add != 0 ) 175 op1.digits.push_back(to_add); 176 return op1; 177 } 178 else{ 179 if (op1.sign) 180 return op1 -= (-op2); 181 else 182 return op1= op2 - (-op1); 183 } 184 185 } 186 187 BigInteger operator-=(BigInteger& op1,const BigInteger& op2){ 188 if( op1.sign == op2.sign ){ //???????????,??????+?? 189 if(op1.sign) { 190 if(op1 < op2) // 2 - 3 191 return op1=-(op2 - op1); 192 } 193 else { 194 if(-op1 > -op2) // (-3)-(-2) = -(3 - 2) 195 return op1=-((-op1)-(-op2)); 196 else // (-2)-(-3) = 3 - 2 197 return op1= (-op2) - (-op1); 198 } 199 vector<char>::iterator iter1; 200 vector<char>::const_iterator iter2; 201 iter1 = op1.digits.begin(); 202 iter2 = op2.digits.begin(); 203 204 char to_substract = 0; //?? 205 206 while ( iter1 != op1.digits.end() && iter2 != op2.digits.end()){ 207 (*iter1) = (*iter1) - (*iter2) - to_substract; 208 to_substract = 0; 209 if( (*iter1) < 0 ){ 210 to_substract=1; 211 (*iter1) += 10; 212 } 213 iter1++; 214 iter2++; 215 } 216 while ( iter1 != op1.digits.end() ){ 217 (*iter1) = (*iter1) - to_substract; 218 to_substract = 0; 219 if( (*iter1) < 0 ){ 220 to_substract=1; 221 (*iter1) += 10; 222 } 223 else break; 224 iter1++; 225 } 226 op1.trim(); 227 return op1; 228 } 229 else{ 230 if (op1 > BigInteger::ZERO) 231 return op1 += (-op2); 232 else 233 return op1 = -(op2 + (-op1)); 234 } 235 } 236 BigInteger operator*=(BigInteger& op1,const BigInteger& op2){ 237 BigInteger result(0); 238 if (op1 == BigInteger::ZERO || op2==BigInteger::ZERO) 239 result = BigInteger::ZERO; 240 else{ 241 vector<char>::const_iterator iter2 = op2.digits.begin(); 242 while( iter2 != op2.digits.end() ){ 243 if(*iter2 != 0){ 244 deque<char> temp(op1.digits.begin() , op1.digits.end()); 245 char to_add = 0; 246 deque<char>::iterator iter1 = temp.begin(); 247 while( iter1 != temp.end() ){ 248 (*iter1) *= (*iter2); 249 (*iter1) += to_add; 250 to_add = (*iter1) / 10; 251 (*iter1) %= 10; 252 iter1++; 253 } 254 if( to_add != 0) 255 temp.push_back( to_add ); 256 int num_of_zeros = iter2 - op2.digits.begin(); 257 while( num_of_zeros--) 258 temp.push_front(0); 259 BigInteger temp2; 260 temp2.digits.insert( temp2.digits.end() , temp.begin() , temp.end() ); 261 temp2.trim(); 262 result = result + temp2; 263 } 264 iter2++; 265 } 266 result.sign = ( (op1.sign && op2.sign) || (!op1.sign && !op2.sign) ); 267 } 268 op1 = result; 269 return op1; 270 } 271 272 BigInteger operator/=(BigInteger& op1 , const BigInteger& op2 ) throw(DividedByZeroException) { 273 if( op2 == BigInteger::ZERO ) 274 throw DividedByZeroException(); 275 BigInteger t1 = op1.abs(), t2 = op2.abs(); 276 if ( t1 < t2 ){ 277 op1 = BigInteger::ZERO; 278 return op1; 279 } 280 //?? t1 > t2 > 0 281 //??? t1/t2?????result???? 282 deque<char> temp; 283 vector<char>::reverse_iterator iter = t1.digits.rbegin(); 284 285 BigInteger temp2(0); 286 while( iter != t1.digits.rend() ){ 287 temp2 = temp2 * BigInteger::TEN + BigInteger( (int)(*iter) ); 288 char s = 0; 289 while( temp2 >= t2 ){ 290 temp2 = temp2 - t2; 291 s = s + 1; 292 } 293 temp.push_front( s ); 294 iter++; 295 } 296 op1.digits.clear(); 297 op1.digits.insert( op1.digits.end() , temp.begin() , temp.end() ); 298 op1.trim(); 299 op1.sign = ( (op1.sign && op2.sign) || (!op1.sign && !op2.sign) ); 300 return op1; 301 } 302 303 BigInteger operator%=(BigInteger& op1,const BigInteger& op2) throw(DividedByZeroException) { 304 return op1 -= ((op1 / op2)*op2); 305 } 306 307 BigInteger operator+(const BigInteger& op1,const BigInteger& op2){ 308 BigInteger temp(op1); 309 temp += op2; 310 return temp; 311 } 312 BigInteger operator-(const BigInteger& op1,const BigInteger& op2){ 313 BigInteger temp(op1); 314 temp -= op2; 315 return temp; 316 } 317 318 BigInteger operator*(const BigInteger& op1,const BigInteger& op2){ 319 BigInteger temp(op1); 320 temp *= op2; 321 return temp; 322 323 } 324 325 BigInteger operator/(const BigInteger& op1,const BigInteger& op2) throw(DividedByZeroException) { 326 BigInteger temp(op1); 327 temp /= op2; 328 return temp; 329 } 330 331 BigInteger operator%(const BigInteger& op1,const BigInteger& op2) throw(DividedByZeroException) { 332 BigInteger temp(op1); 333 temp %= op2; 334 return temp; 335 } 336 337 //uniary operators 338 BigInteger operator-(const BigInteger& op){ //negative 339 BigInteger temp = BigInteger(op); 340 temp.sign = !temp.sign; 341 return temp; 342 } 343 344 BigInteger operator++(BigInteger& op){ //++v 345 op += BigInteger::ONE; 346 return op; 347 } 348 349 BigInteger operator++(BigInteger& op,int x){ //v++ 350 BigInteger temp(op); 351 ++op; 352 return temp; 353 } 354 355 BigInteger operator--(BigInteger& op){ //--v 356 op -= BigInteger::ONE; 357 return op; 358 } 359 360 BigInteger operator--(BigInteger& op,int x){ //v-- 361 BigInteger temp(op); 362 --op; 363 return temp; 364 } 365 366 bool operator<(const BigInteger& op1,const BigInteger& op2){ 367 if( op1.sign != op2.sign ) 368 return !op1.sign; 369 else{ 370 if(op1.digits.size() != op2.digits.size()) 371 return (op1.sign && op1.digits.size()<op2.digits.size()) 372 || (!op1.sign && op1.digits.size()>op2.digits.size()); 373 vector<char>::const_reverse_iterator iter1,iter2; 374 iter1 = op1.digits.rbegin();iter2 = op2.digits.rbegin(); 375 while( iter1 != op1.digits.rend() ){ 376 if( op1.sign && *iter1 < *iter2 ) return true; 377 if( op1.sign && *iter1 > *iter2 ) return false; 378 if( !op1.sign && *iter1 > *iter2 ) return true; 379 if( !op1.sign && *iter1 < *iter2 ) return false; 380 iter1++; 381 iter2++; 382 } 383 return false; 384 } 385 } 386 bool operator==(const BigInteger& op1,const BigInteger& op2){ 387 if( op1.sign != op2.sign || op1.digits.size() != op2.digits.size() ) 388 return false; 389 vector<char>::const_iterator iter1,iter2; 390 iter1 = op1.digits.begin(); 391 iter2 = op2.digits.begin(); 392 while( iter1!= op1.digits.end() ){ 393 if( *iter1 != *iter2 ) return false; 394 iter1++; 395 iter2++; 396 } 397 return true; 398 } 399 400 bool operator!=(const BigInteger& op1,const BigInteger& op2){ 401 return !(op1==op2); 402 } 403 404 bool operator>=(const BigInteger& op1,const BigInteger& op2){ 405 return (op1>op2) || (op1==op2); 406 } 407 408 bool operator<=(const BigInteger& op1,const BigInteger& op2){ 409 return (op1<op2) || (op1==op2); 410 } 411 412 bool operator>(const BigInteger& op1,const BigInteger& op2){ 413 return !(op1<=op2); 414 } 415 416 ostream& operator<<(ostream& stream,const BigInteger& val){ //print the BigInteger 417 if (!val.sign) 418 stream << "-"; 419 for ( vector<char>::const_reverse_iterator iter = val.digits.rbegin(); iter != val.digits.rend() ; iter++) 420 stream << (char)((*iter) + '0'); 421 return stream; 422 } 423 424 istream& operator>>(istream& stream, BigInteger& val){ //Input the BigInteger 425 string str; 426 stream >> str; 427 val=BigInteger(str); 428 return stream; 429 } 430 431 BigInteger f[5005]; 432 signed main() 433 { 434 int n; 435 cin>>n; 436 if(n==2){cout<<5<<endl;return 0;} 437 f[1]=4,f[2]=7; 438 for(int i=3;i<=505;i++) f[i]=f[i-1]+f[i-2]; 439 BigInteger ans=f[n-2]; 440 ans*=ans; 441 if(!(n&1)) ans-=4; 442 cout<<ans; 443 return 0; 444 }