BZOJ 1002 [FJOI2007]轮状病毒
1002: [FJOI2007]轮状病毒
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3106 Solved: 1724
[Submit][Status][Discuss]
Description
给定n(N<=100),编程计算有多少个不同的n轮状病毒。
Input
第一行有1个正整数n。
Output
将编程计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
HINT
Source
题解:貌似考的是基尔霍夫矩阵(<-什么破玩意?)
算法引入:
给定一个无向图G,求它生成树的个数t(G);
算法思想:
(1)G的度数矩阵D[G]是一个n*n的矩阵,并且满足:当i≠j时,dij=0;当i=j时,dij等于vi的度数;
(2)G的邻接矩阵A[G]是一个n*n的矩阵,并且满足:如果vi,vj之间有边直接相连,则aij=1,否则为0;
定义图G的Kirchhoff矩阵C[G]为C[G]=D[G]-A[G];
*Matrix-Tree定理:G的所有不同的生成树的个数等于其Kirchhoff矩阵C[G]任何一个n-1阶主子式的行列式的绝对值;
所谓n-1阶主子式,就是对于r(1≤r≤n),将C[G]的第r行,第r列同时去掉后得到的新矩阵,用Cr[G]表示;
*Kirchhoff矩阵的特殊性质:
(1)对于任何一个图G,它的Kirchhoff矩阵C的行列式总是0,这是因为C每行每列所有元素的和均为0;
(2)如果G是不连通的,则它的Kirchhoff矩阵C的任一个主子式的行列式均为0;
(3)如果G是一颗树,那么它的Kirchhoff矩阵C的任一个n-1阶主子式的行列式均为1;
扯了这么多,其实这道题根本用不上,只要知道这玩意能推出f[i]=(f[i-1]*3-f[i-2]+2)就行了。注意高精度。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 #define eps 1e-8 10 using namespace std; 11 const int maxn=105; 12 struct bign{ 13 int len,s[maxn]; 14 bign(){memset(s,0,sizeof(s));len=1;} 15 bign(int num){*this=num;} 16 bign(const char *num){*this=num;} 17 bign operator = (const int num){ 18 char s[maxn]; sprintf(s,"%d",num); 19 *this = s;return *this; 20 } 21 bign operator = (const char *num){ 22 for(int i=0;num[i]=='0';num++); 23 len=strlen(num); 24 for(int i=0;i<len;i++) s[i]=num[len-i-1]-'0'; 25 return *this; 26 } 27 bign operator + (const bign &b) const{ 28 bign c;c.len=0; 29 for(int i=0,g=0;g||i<max(len,b.len);i++) { 30 int x=g; 31 if(i<len) x+=s[i]; 32 if(i<b.len) x+=b.s[i]; 33 c.s[c.len++]=x%10; 34 g=x/10; 35 } return c; 36 } 37 void clean(){while(len > 1 && !s[len-1]) len--;return;} 38 bign operator * (const bign &b){ 39 bign c; 40 c.len=len+b.len; 41 for(int i=0;i<len;i++) for(int j=0;j<b.len;j++) c.s[i+j]+=s[i]*b.s[j]; 42 for(int i=0;i<c.len;i++){ 43 c.s[i+1]+=c.s[i]/10; 44 c.s[i]%=10; 45 } c.clean();return c; 46 } 47 bign operator - (const bign &b){ 48 bign c;c.len=0; 49 for(int i=0,g=0;i<len;i++){ 50 int x=s[i]-g;if(i<b.len) x-=b.s[i]; 51 if(x>=0) g=0; 52 else g=1,x+=10; 53 c.s[c.len++]=x; 54 } c.clean();return c; 55 } 56 bign operator / (const bign &b) { 57 bign c,f=0; 58 for(int i=len-1;i>=0;i--){ 59 f=f*10;f.s[0]=s[i]; 60 while(!(f<b)) f=f-b,c.s[i]++; 61 } c.len=len;c.clean();return c; 62 } 63 bign operator % (const bign &b) { 64 bign r = *this / b; 65 r = *this - r*b; 66 return r; 67 } 68 bool operator < (const bign &b) { 69 if(len!=b.len) return len<b.len; 70 for(int i=len-1;i>=0;i--){ 71 if(s[i]!=b.s[i]) return s[i]<b.s[i]; 72 } return false; 73 } 74 bool operator > (const bign &b){ 75 if(len!=b.len) return len>b.len; 76 for(int i=len-1;i>=0;i--){ 77 if(s[i]!=b.s[i]) return s[i]>b.s[i]; 78 } return false; 79 } 80 bool operator == (const bign &b){ 81 return !(*this>b)&&!(*this<b); 82 } 83 bool operator >= (const bign &b){ 84 return (*this>b)||(*this==b); 85 } 86 void print(){ 87 for(int i=len-1;i>=0;i--) putchar(s[i]+'0');return; 88 } 89 }f[maxn]; 90 inline int read(){ 91 int x=0,sig=1;char ch=getchar(); 92 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 93 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 94 return x*=sig; 95 } 96 inline void write(int x){ 97 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 98 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 99 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 100 } 101 int n; 102 void init(){ 103 n=read();f[1]=1;f[2]=5; 104 return; 105 } 106 void work(){ 107 for(int i=3;i<=n;i++) f[i]=f[i-1]*3-f[i-2]+2; 108 return; 109 } 110 void print(){ 111 f[n].print(); 112 return; 113 } 114 int main(){init();work();print();}
然后窝萌来打表好辣~
打表代码生成器:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 #define eps 1e-8 10 using namespace std; 11 const int maxn=105; 12 struct bign{ 13 int len,s[maxn]; 14 bign(){memset(s,0,sizeof(s));len=1;} 15 bign(int num){*this=num;} 16 bign(const char *num){*this=num;} 17 bign operator = (const int num){ 18 char s[maxn]; sprintf(s,"%d",num); 19 *this = s;return *this; 20 } 21 bign operator = (const char *num){ 22 for(int i=0;num[i]=='0';num++); 23 len=strlen(num); 24 for(int i=0;i<len;i++) s[i]=num[len-i-1]-'0'; 25 return *this; 26 } 27 bign operator + (const bign &b) const{ 28 bign c;c.len=0; 29 for(int i=0,g=0;g||i<max(len,b.len);i++) { 30 int x=g; 31 if(i<len) x+=s[i]; 32 if(i<b.len) x+=b.s[i]; 33 c.s[c.len++]=x%10; 34 g=x/10; 35 } return c; 36 } 37 void clean(){while(len > 1 && !s[len-1]) len--;return;} 38 bign operator * (const bign &b){ 39 bign c; 40 c.len=len+b.len; 41 for(int i=0;i<len;i++) for(int j=0;j<b.len;j++) c.s[i+j]+=s[i]*b.s[j]; 42 for(int i=0;i<c.len;i++){ 43 c.s[i+1]+=c.s[i]/10; 44 c.s[i]%=10; 45 } c.clean();return c; 46 } 47 bign operator - (const bign &b){ 48 bign c;c.len=0; 49 for(int i=0,g=0;i<len;i++){ 50 int x=s[i]-g;if(i<b.len) x-=b.s[i]; 51 if(x>=0) g=0; 52 else g=1,x+=10; 53 c.s[c.len++]=x; 54 } c.clean();return c; 55 } 56 bign operator / (const bign &b) { 57 bign c,f=0; 58 for(int i=len-1;i>=0;i--){ 59 f=f*10;f.s[0]=s[i]; 60 while(!(f<b)) f=f-b,c.s[i]++; 61 } c.len=len;c.clean();return c; 62 } 63 bign operator % (const bign &b) { 64 bign r = *this / b; 65 r = *this - r*b; 66 return r; 67 } 68 bool operator < (const bign &b) { 69 if(len!=b.len) return len<b.len; 70 for(int i=len-1;i>=0;i--){ 71 if(s[i]!=b.s[i]) return s[i]<b.s[i]; 72 } return false; 73 } 74 bool operator > (const bign &b){ 75 if(len!=b.len) return len>b.len; 76 for(int i=len-1;i>=0;i--){ 77 if(s[i]!=b.s[i]) return s[i]>b.s[i]; 78 } return false; 79 } 80 bool operator == (const bign &b){ 81 return !(*this>b)&&!(*this<b); 82 } 83 bool operator >= (const bign &b){ 84 return (*this>b)||(*this==b); 85 } 86 void print(){ 87 for(int i=len-1;i>=0;i--) putchar(s[i]+'0');return; 88 } 89 }f[maxn]; 90 inline int read(){ 91 int x=0,sig=1;char ch=getchar(); 92 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 93 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 94 return x*=sig; 95 } 96 inline void write(int x){ 97 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 98 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 99 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 100 } 101 int n; 102 void init(){ 103 f[1]=1;f[2]=5; 104 return; 105 } 106 void work(){ 107 for(int i=3;i<=100;i++) f[i]=f[i-1]*3-f[i-2]+2; 108 return; 109 } 110 void print(){ 111 freopen("dabiao.txt","w",stdout); 112 puts("if(n==1)puts(\"1\");"); 113 for(int i=2;i<=100;i++){ 114 printf("else if(n==%d)puts(\"",i);f[i].print();puts("\");"); 115 } 116 return; 117 } 118 int main(){init();work();print();}
打表代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 using namespace std; 10 inline int read(){ 11 int x=0,sig=1;char ch=getchar(); 12 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 13 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 14 return x*=sig; 15 } 16 inline void write(int x){ 17 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 18 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 19 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 20 } 21 int n; 22 void init(){ 23 n=read(); 24 if(n==1)puts("1"); 25 else if(n==2)puts("5"); 26 else if(n==3)puts("16"); 27 else if(n==4)puts("45"); 28 else if(n==5)puts("121"); 29 else if(n==6)puts("320"); 30 else if(n==7)puts("841"); 31 else if(n==8)puts("2205"); 32 else if(n==9)puts("5776"); 33 else if(n==10)puts("15125"); 34 else if(n==11)puts("39601"); 35 else if(n==12)puts("103680"); 36 else if(n==13)puts("271441"); 37 else if(n==14)puts("710645"); 38 else if(n==15)puts("1860496"); 39 else if(n==16)puts("4870845"); 40 else if(n==17)puts("12752041"); 41 else if(n==18)puts("33385280"); 42 else if(n==19)puts("87403801"); 43 else if(n==20)puts("228826125"); 44 else if(n==21)puts("599074576"); 45 else if(n==22)puts("1568397605"); 46 else if(n==23)puts("4106118241"); 47 else if(n==24)puts("10749957120"); 48 else if(n==25)puts("28143753121"); 49 else if(n==26)puts("73681302245"); 50 else if(n==27)puts("192900153616"); 51 else if(n==28)puts("505019158605"); 52 else if(n==29)puts("1322157322201"); 53 else if(n==30)puts("3461452808000"); 54 else if(n==31)puts("9062201101801"); 55 else if(n==32)puts("23725150497405"); 56 else if(n==33)puts("62113250390416"); 57 else if(n==34)puts("162614600673845"); 58 else if(n==35)puts("425730551631121"); 59 else if(n==36)puts("1114577054219520"); 60 else if(n==37)puts("2918000611027441"); 61 else if(n==38)puts("7639424778862805"); 62 else if(n==39)puts("20000273725560976"); 63 else if(n==40)puts("52361396397820125"); 64 else if(n==41)puts("137083915467899401"); 65 else if(n==42)puts("358890350005878080"); 66 else if(n==43)puts("939587134549734841"); 67 else if(n==44)puts("2459871053643326445"); 68 else if(n==45)puts("6440026026380244496"); 69 else if(n==46)puts("16860207025497407045"); 70 else if(n==47)puts("44140595050111976641"); 71 else if(n==48)puts("115561578124838522880"); 72 else if(n==49)puts("302544139324403592001"); 73 else if(n==50)puts("792070839848372253125"); 74 else if(n==51)puts("2073668380220713167376"); 75 else if(n==52)puts("5428934300813767249005"); 76 else if(n==53)puts("14213134522220588579641"); 77 else if(n==54)puts("37210469265847998489920"); 78 else if(n==55)puts("97418273275323406890121"); 79 else if(n==56)puts("255044350560122222180445"); 80 else if(n==57)puts("667714778405043259651216"); 81 else if(n==58)puts("1748099984655007556773205"); 82 else if(n==59)puts("4576585175559979410668401"); 83 else if(n==60)puts("11981655542024930675232000"); 84 else if(n==61)puts("31368381450514812615027601"); 85 else if(n==62)puts("82123488809519507169850805"); 86 else if(n==63)puts("215002084978043708894524816"); 87 else if(n==64)puts("562882766124611619513723645"); 88 else if(n==65)puts("1473646213395791149646646121"); 89 else if(n==66)puts("3858055874062761829426214720"); 90 else if(n==67)puts("10100521408792494338631998041"); 91 else if(n==68)puts("26443508352314721186469779405"); 92 else if(n==69)puts("69230003648151669220777340176"); 93 else if(n==70)puts("181246502592140286475862241125"); 94 else if(n==71)puts("474509504128269190206809383201"); 95 else if(n==72)puts("1242282009792667284144565908480"); 96 else if(n==73)puts("3252336525249732662226888342241"); 97 else if(n==74)puts("8514727565956530702536099118245"); 98 else if(n==75)puts("22291846172619859445381409012496"); 99 else if(n==76)puts("58360810951903047633608127919245"); 100 else if(n==77)puts("152790586683089283455442974745241"); 101 else if(n==78)puts("400010949097364802732720796316480"); 102 else if(n==79)puts("1047242260609005124742719414204201"); 103 else if(n==80)puts("2741715832729650571495437446296125"); 104 else if(n==81)puts("7177905237579946589743592924684176"); 105 else if(n==82)puts("18791999880010189197735341327756405"); 106 else if(n==83)puts("49198094402450621003462431058585041"); 107 else if(n==84)puts("128802283327341673812651951847998720"); 108 else if(n==85)puts("337208755579574400434493424485411121"); 109 else if(n==86)puts("882823983411381527490828321608234645"); 110 else if(n==87)puts("2311263194654570182037991540339292816"); 111 else if(n==88)puts("6050965600552329018623146299409643805"); 112 else if(n==89)puts("15841633607002416873831447357889638601"); 113 else if(n==90)puts("41473935220454921602871195774259272000"); 114 else if(n==91)puts("108580172054362347934782139964888177401"); 115 else if(n==92)puts("284266580942632122201475224120405260205"); 116 else if(n==93)puts("744219570773534018669643532396327603216"); 117 else if(n==94)puts("1948392131377969933807455373068577549445"); 118 else if(n==95)puts("5100956823360375782752722586809405045121"); 119 else if(n==96)puts("13354478338703157414450712387359637585920"); 120 else if(n==97)puts("34962478192749096460599414575269507712641"); 121 else if(n==98)puts("91532956239544131967347531338448885552005"); 122 else if(n==99)puts("239636390525883299441443179440077148943376"); 123 else if(n==100)puts("627376215338105766356982006981782561278125"); 124 return; 125 } 126 void work(){ 127 return; 128 } 129 void print(){ 130 return; 131 } 132 int main(){init();work();print();return 0;}