luogu P2144 [FJOI2007] 轮状病毒
明显的生成树
所以矩阵统计完全图的生成树计数就OK
......原地懵逼
并不会行列式
等等 完全图
果断列了一个矩阵(主对角线N*(N-1)/2,其他(N-1))
(当然是3*3矩阵和4*4矩阵)
然后搞了一个互相推
....30minutes later......
两个矩阵推不出来 试试三个
(当然是2,3,4)
....20minutes later......
发现满足f[n] = f[n-1] * 3 - f[n-2] + 2 (鬼知道我是怎么发现的)
1和2可以手胡
然后n<=100...int256都炸了吧
跪着写高精...
Time cost : 115min
(真要考试遇上这题不得godie)
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #define ms(a,b) memset(a,b,sizeof a) 6 #define rep(i,a,n) for(int i = a;i <= n;i++) 7 #define per(i,n,a) for(int i = n;i >= a;i--) 8 #define inf 1000000007 9 using namespace std; 10 typedef long long ll; 11 typedef double D; 12 #define eps 1e-8 13 ll read() { 14 ll as = 0,fu = 1; 15 char c = getchar(); 16 while(c < '0' || c > '9') { 17 if(c == '-') fu = -1; 18 c = getchar(); 19 } 20 while(c >= '0' && c <= '9') { 21 as = as * 10 + c - '0'; 22 c = getchar(); 23 } 24 return as * fu; 25 } 26 //head 27 28 struct Big { 29 const static int N = 5005; 30 int a[N]; 31 bool flag; 32 Big(){} 33 Big( ll x ){ 34 ms(a,0),flag = 0; 35 flag = (x < 0); 36 x = max(x,-x); 37 while(x) a[++a[0]] = x%10,x/=10; 38 clr0(); 39 } 40 void read() { 41 ms(a,0),flag = 0; 42 char s[N]; 43 scanf("%s",s+1); 44 a[0] = strlen(s+1); 45 if(s[1] == '-') a[0]--,flag = 1; 46 rep(i,1,a[0]) a[i] = s[a[0] - i + flag + 1] - '0'; 47 clr0(); 48 } 49 void clr0() { 50 while(a[0] && a[a[0]] == 0) a[0]--; 51 while(a[0] < 0) a[0]++; 52 if(a[0] == 0) flag = 0; 53 } 54 void print() { 55 clr0(); 56 if(!a[0]) return void(puts("0")); 57 if(flag) putchar('-'); 58 per(i,a[0],1) putchar(a[i] + '0'); 59 putchar('\n'); 60 } 61 //clr0 before use 62 bool operator < (const Big &o) const { 63 if(o.a[0] == 0) return flag; 64 if(a[0] == 0) return !o.flag; 65 if(flag ^ o.flag) return flag; 66 if(flag) { 67 rep(i,0,a[0]) { 68 if(a[i] > o.a[i]) return 1; 69 if(a[i] < o.a[i]) return 0; 70 } 71 return 0; 72 } else { 73 rep(i,0,a[0]) { 74 if(a[i] < o.a[i]) return 1; 75 if(a[i] > o.a[i]) return 0; 76 } 77 return 0; 78 } 79 } 80 bool operator == (const Big &o) const { 81 Big r = *this; 82 return !(r < o || o < r); 83 } 84 //保证同号 85 Big operator + (const Big &o) const { 86 if(a[0] == 0) return o; 87 if(o.a[0] == 0) return *this; 88 if(flag ^ o.flag) { 89 Big x = *this,y = o; 90 if(x.flag) { 91 x.flag = 0; 92 return y - x; 93 } 94 else { 95 y.flag = 0; 96 return x - y; 97 } 98 } 99 Big ans; 100 ms(ans.a,0); 101 ans.a[0] = max(a[0],o.a[0]),ans.flag = flag; 102 rep(i,1,ans.a[0]) { 103 ans.a[i] += a[i] + o.a[i]; 104 if(i == ans.a[0] && ans.a[i] >= 10) { 105 ans.a[0]++; 106 } 107 ans.a[i+1] += ans.a[i] / 10; 108 ans.a[i] %= 10; 109 } 110 return ans; 111 } 112 //保证同号 113 Big operator - (const Big &o) const { 114 Big x = *this; 115 Big y = o; 116 if(flag ^ o.flag) { 117 y.flag ^= 1; 118 return x + y; 119 } 120 Big ans; 121 ms(ans.a,0); 122 ans.a[0] = ans.flag = 0; 123 ans.flag = flag; 124 x.flag = y.flag = 0; 125 if(x == y) return ans; 126 if(x < y) swap(x,y),ans.flag ^= 1; 127 rep(i,1,x.a[0]) { 128 if(x.a[i] < y.a[i]) x.a[i] += 10,x.a[i+1]--; 129 ans.a[i] = x.a[i] - y.a[i]; 130 } 131 ans.a[0] = x.a[0]; 132 ans.clr0(); 133 return ans; 134 } 135 //O(n^2) 高精乘 136 Big operator * (const Big &o) const { 137 if(a[0] == 0) return *this; 138 if(o.a[0] == 0) return o; 139 Big ans; 140 ms(ans.a,0); 141 ans.a[0] = a[0] + o.a[0],ans.flag = o.flag ^ flag; 142 rep(i,1,a[0]) rep(j,1,o.a[0]) 143 ans.a[i+j-1] += a[i] * o.a[j]; 144 rep(i,1,ans.a[0]) { 145 if(i == ans.a[0] && ans.a[i] >= 10) ans.a[0]++; 146 ans.a[i+1] += ans.a[i] / 10; 147 ans.a[i] %= 10; 148 } 149 return ans; 150 } 151 }x,y,z; 152 Big zero = Big(0); 153 Big one = Big(1); 154 Big two = Big(2); 155 Big three = Big(3); 156 void tst() { 157 while(1) { 158 x.read(),y.read(); 159 z = x + y; 160 printf("plus:"),z.print(); 161 z = x - y; 162 printf("minus:"),z.print(); 163 z = x * y; 164 printf("mult:"),z.print(); 165 } 166 } 167 168 #define Max(a,b) ((b)>(a)?(a):(b)) 169 #define Min(a,b) ((a)<(b)?(a):(b)) 170 int n,m; 171 const int N = 105; 172 Big f[N]; 173 174 int main() { 175 n = read(); 176 f[1] = one; 177 f[2] = Big(5); 178 rep(i,3,n) f[i] = three * f[i-1] - f[i-2] + two; 179 f[n].print(); 180 return 0; 181 }
> 别忘了 总有人在等着你