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 }

 

posted @ 2018-11-03 16:29  白怀潇  阅读(143)  评论(0编辑  收藏  举报