题目是洛谷 p1005 矩阵取数游戏 很水的题

重要的是高精度的板子 太牛皮了

  1 #include <iostream>
  2 #include <iomanip>
  3 #include <vector>
  4 #include <cassert>
  5 #include <cstring>
  6 #include <string>
  7 #include <sstream>
  8
  9 using namespace std;
 10 #define N 82
 11 typedef long long LL;
 12
 13 int MyAtoi(const char* s, const char* t) {
 14     int ans = 0;
 15     for (; s != t; ++s)
 16         (ans *= 10) += *s - '0';
 17     return ans;
 18 }
 19
 20 template<typename T, typename MT>
 21 MT Add(T x, MT p) {
 22     return x >= p ? x - p : x;
 23 }
 24
 25 const LL tens[] = {1LL,10LL,100LL,1000LL,10000LL,100000LL,1000000LL,10000000LL,100000000LL,1000000000LL};
 26 const int pow2[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824
 27                    };
 28 struct UnsignedBigInt {
 29     static const int BASE = 1000000000;
 30     static const int WIDTH = 9;
 31
 32     vector <int> s;
 33
 34     UnsignedBigInt() {}
 35     __attribute__((optimize("O3"))) explicit UnsignedBigInt(int num) {
 36         assert(num >= 0);
 37         if (num)
 38             s.push_back(num);
 39     }
 40     explicit UnsignedBigInt(LL num) {
 41         assert(num >= 0);
 42         while (num) {
 43             s.push_back(num % BASE);
 44             num /= BASE;
 45         }
 46     }
 47     explicit UnsignedBigInt(const string& str) {
 48         *this = str;
 49     }
 50     explicit UnsignedBigInt(const char* str) {
 51         *this = str;
 52     }
 53     explicit UnsignedBigInt(const vector<int>& in): s(in) {
 54         clean();
 55     }
 56     UnsignedBigInt& clean() {
 57         while(!s.empty() && !s.back())
 58             s.pop_back();
 59         return *this;
 60     }
 61
 62     explicit operator int() const {
 63         return s.empty() ? 0 : s[0];
 64     }
 65     explicit operator double() const {
 66         double ans = 1;
 67         double k = 1;
 68         for (size_t i = 0; i < s.size(); ++i, k *= BASE)
 69             ans *= k * s[i];
 70         return ans;
 71     }
 72     explicit operator string() const {
 73         ostringstream ans;
 74         if (s.empty()) {
 75             ans << '0';
 76         } else {
 77             ans << s.back();
 78             for(int i = (int)s.size()-2; i >= 0; --i)
 79                 ans << setfill('0') << setw(WIDTH) << s[i];
 80         }
 81         return ans.str();
 82     }
 83     explicit operator bool() const {
 84         return !s.empty();
 85     }
 86
 87     UnsignedBigInt& operator = (const int num) {
 88         return *this = UnsignedBigInt(num);
 89     }
 90     UnsignedBigInt& operator = (LL num) {
 91         return *this = UnsignedBigInt(num);
 92     }
 93     UnsignedBigInt& assign(const char* str, int ended) {
 94         s.clear();
 95         for (; ended > 0; ended -= WIDTH)
 96             s.push_back(MyAtoi(str + max(0, ended - WIDTH), str + ended));
 97         return clean();
 98     }
 99     UnsignedBigInt& operator = (const string& str) {
100         return assign(str.c_str(), str.length());
101     }
102     UnsignedBigInt& operator = (const char* str) {
103         return assign(str, strlen(str));
104     }
105
106     UnsignedBigInt& AddEq(const UnsignedBigInt& b, int as = 0, int bs = 0) {
107         int rem = 0;
108         if (s.size() < as)
109             s.resize(as, 0);
110         for (; bs < b.s.size() || rem; ++as, ++bs) {
111             if (as == s.size())
112                 s.push_back(rem);
113             else
114                 s[as] += rem;
115             rem = 0;
116             if (bs < b.s.size())
117                 s[as] += b.s[bs];
118             if (s[as] >= BASE) {
119                 s[as] -= BASE;
120                 rem = 1;
121             }
122         }
123         return *this;
124     }
125     UnsignedBigInt& operator += (const UnsignedBigInt& b) {
126         return AddEq(b);
127     }
128     UnsignedBigInt operator + (const UnsignedBigInt& b) const {
129         return UnsignedBigInt(*this) += b;
130     }
131
132     UnsignedBigInt& operator += (int b) {
133         assert(0 <= b && b < BASE);
134         for (size_t i = 0; b; ++i) {
135             if (i == s.size())
136                 s.push_back(0);
137             s[i] += b;
138             if (s[i] > BASE) {
139                 b = 1;
140                 s[i] -= BASE;
141             } else {
142                 b = 0;
143             }
144         }
145         return *this;
146     }
147     UnsignedBigInt operator + (int b) const {
148         return UnsignedBigInt(*this) += b;
149     }
150
151     UnsignedBigInt& operator *= (int num) {
152         assert(0 <= num && num < BASE);
153         if(num) {
154             LL rem = 0;
155             for (int& v : s) {
156                 rem += (LL)v * num;
157                 v = rem % BASE;
158                 rem /= BASE;
159             }
160             if(rem)
161                 s.push_back(rem);
162         } else {
163             s.clear();
164         }
165         return *this;
166     }
167     inline UnsignedBigInt operator * (int num) const {
168         return UnsignedBigInt(*this) *= num;
169     }
170     friend UnsignedBigInt operator * (int a, const UnsignedBigInt& b);
171     UnsignedBigInt operator * (const UnsignedBigInt& b) const {
172         UnsignedBigInt ans; //0
173         for (size_t j = 0; j < b.s.size(); ++j)
174             ans.AddEq(*this * b.s[j], j);
175         return ans;
176     }
177     UnsignedBigInt& operator *= (const UnsignedBigInt& b) {
178         return *this = *this * b;
179     }
180
181     int cmp(const UnsignedBigInt& b) const {
182         if (s.size() != b.s.size()) {
183             return (int) s.size() - (int) b.s.size();
184         } else if (s.size() == 0 && b.s.size() == 0) {
185             return 0;
186         } else {
187             int i;
188             for(i = (int)s.size()-1; i > 0 && s[i] == b.s[i]; --i);
189
190             return s[i] - b.s[i];
191         }
192     }
193     bool operator < (const UnsignedBigInt& b) const {
194         return cmp(b) < 0;
195     }
196     bool operator > (const UnsignedBigInt& b)const {
197         return cmp(b) > 0;
198     }
199     bool operator == (const UnsignedBigInt& b)const {
200         return cmp(b) == 0;
201     }
202     bool operator != (const UnsignedBigInt& b) const {
203         return cmp(b) != 0;
204     }
205     bool operator <= (const UnsignedBigInt& b)const {
206         return cmp(b) <= 0;
207     }
208     bool operator >= (const UnsignedBigInt& b)const {
209         return cmp(b) >= 0;
210     }
211
212     //0 <= b < BASE
213     bool operator == (int b) const {
214         return s.size() == 1 ? (s[0] == b) : (s.size() ? false : b == 0);
215     }
216     bool operator < (int b) const {
217         return s.size() == 1 ? (s[0] < b) : (s.size() ? false : b != 0);
218     }
219     bool operator <= (int rhs) const {
220         return *this < rhs || *this == rhs;
221     }
222     bool operator >= (int rhs) const {
223         return !(*this < rhs);
224     }
225     bool operator > (int rhs) const {
226         return !(*this <= rhs);
227     }
228     bool operator != (int rhs) const {
229         return !(*this == rhs);
230     }
231
232     friend bool operator < (int lhs, const UnsignedBigInt& rhs);
233     friend bool operator == (int lhs, const UnsignedBigInt& rhs);
234     friend bool operator <= (int lhs, const UnsignedBigInt& rhs);
235     friend bool operator > (int lhs, const UnsignedBigInt& rhs);
236     friend bool operator >= (int lhs, const UnsignedBigInt& rhs);
237     friend bool operator != (int lhs, const UnsignedBigInt& rhs);
238
239     UnsignedBigInt& operator -= (const UnsignedBigInt& b) {
240         assert(*this >= b);
241         int r = 0;
242         size_t i;
243         for(i = 0; i < b.s.size(); ++i) {
244             s[i] -= b.s[i] + r;
245             if(s[i] < 0) {
246                 s[i] += BASE;
247                 r = 1;
248             } else {
249                 r = 0;
250             }
251         }
252         while(r) {  //i < s.size()
253             if(--s[i] < 0)
254                 s[i++] += BASE;
255             else
256                 r = 0;
257         }
258         return clean();
259     }
260     UnsignedBigInt operator - (const UnsignedBigInt& b) const {
261         return UnsignedBigInt(*this) -= b;
262     }
263
264     UnsignedBigInt& operator -= (int b) {
265         assert(*this >= b);
266         size_t i = 0;
267         while (b) {
268             if((s[i] -= b) < 0) {
269                 s[i++] += BASE;
270                 b = 1;
271             } else {
272                 b = 0;
273             }
274         }
275         return clean();
276     }
277     UnsignedBigInt operator - (int b) const {
278         return UnsignedBigInt(*this) -= b;
279     }
280
281     friend int operator - (int lhs, const UnsignedBigInt& rhs);
282
283     int DivEq_Mod(int rhs) {
284         assert(rhs);
285         LL rem = 0;
286         for (int i = s.size()-1; i >= 0; --i) {
287             rem = rem * BASE + s[i];
288             s[i] = rem / rhs;
289             rem %= rhs;
290         }
291         clean();
292         return rem;
293     }
294     int operator % (int rhs) const {
295         return UnsignedBigInt(*this).DivEq_Mod(rhs);
296     }
297     UnsignedBigInt& operator /= (int rhs) {
298         DivEq_Mod(rhs);
299         return *this;
300     }
301     UnsignedBigInt operator / (int rhs) {
302         UnsignedBigInt ans = *this;
303         ans.DivEq_Mod(rhs);
304         return ans;
305     }
306     UnsignedBigInt& operator %= (int rhs) {
307         return *this = DivEq_Mod(rhs);
308     }
309
310     //You should make sure that ans == 0 before invoke the function.
311     __attribute__((optimize("O3"))) void div_mod(const UnsignedBigInt& b, UnsignedBigInt& ans, UnsignedBigInt& rem) const {
312         assert(!b.s.empty());
313         UnsignedBigInt expNum(1), divisor(b);
314
315         rem = *this;
316         while(divisor <= rem) {
317             divisor *= 2;
318             expNum *= 2;
319         }
320         divisor /= 2;
321         expNum /= 2;
322         while(!expNum.s.empty()) {
323             if(rem >= divisor) {
324                 rem -= divisor;
325                 ans += expNum;
326             }
327             divisor /= 2;
328             expNum /= 2;
329         }
330         ans.clean();
331     }
332     __attribute__((optimize("O3"))) UnsignedBigInt operator / (const UnsignedBigInt& b)const {
333         UnsignedBigInt ans, rem; //ans = remain = 0;
334         div_mod(b, ans, rem);
335         return ans;
336     }
337     __attribute__((optimize("O3"))) UnsignedBigInt& operator /= (const UnsignedBigInt& b) {
338         return *this = *this / b;
339     }
340
341     //void div_mod(const UnsignedBigInt& b, UnsignedBigInt& ans, UnsignedBigInt& rem)
342     __attribute__((optimize("O3"))) UnsignedBigInt operator % (const UnsignedBigInt& b) const {
343         UnsignedBigInt ans, rem; //ans = remain = 0;
344         div_mod(b, ans, rem);
345         return rem;
346     }
347     __attribute__((optimize("O3"))) UnsignedBigInt& operator %= (const UnsignedBigInt& b) {
348         return *this = *this % b;
349     }
350
351     __attribute__((optimize("O3"))) inline UnsignedBigInt Move_right_BASE(int n) const {
352         return n >= (int)s.size() ? UnsignedBigInt() : UnsignedBigInt(vector<int>(s.begin() + n, s.end()));
353     }
354
355     __attribute__((optimize("O3"))) UnsignedBigInt& MoveEq_right_small_10(int n) {
356         assert(n < WIDTH);
357         LL rem = 0;
358         for(int i = (int)s.size() - 1; i >= 0; --i) {
359             (rem *= BASE) += s[i];
360             s[i] = rem / tens[n];
361             rem %= tens[n];
362         }
363         return clean();
364     }
365     __attribute__((optimize("O3"))) inline UnsignedBigInt Move_right_10(int n) const {
366         return Move_right_BASE(n / WIDTH).MoveEq_right_small_10(n % WIDTH);
367     }
368
369     __attribute__((optimize("O3"))) inline UnsignedBigInt Move_left_BASE(int n) {
370         UnsignedBigInt ans = *this;
371         ans.s.insert(ans.s.begin(), n, 0);
372         return ans;
373     }
374
375     __attribute__((optimize("O3"))) UnsignedBigInt operator ^ (int m) const {
376         if(0 == m)
377             return UnsignedBigInt(1);
378         assert(m > 0);
379         UnsignedBigInt ans = *this;
380         while(--m)
381             ans *= *this;
382         return ans;
383     }
384
385     //Independent
386     //Number of digits in decimal
387     size_t digit() const {
388         size_t ans;
389         if(s.size()) {
390             ans = ((int)s.size() - 1) * WIDTH;
391             for(int t = s.back(); t; t /= 10, ++ans);
392         } else {
393             ans = 0;
394         }
395         return ans;
396     }
397 };
398
399 UnsignedBigInt operator * (int a, const UnsignedBigInt& b) {
400     return b * a;
401 }
402
403 int operator - (int lhs, const UnsignedBigInt& rhs) {
404     assert(lhs >= rhs);
405     return lhs - (int)rhs;
406 }
407
408 bool operator < (int lhs, const UnsignedBigInt& rhs) {
409     return rhs.s.size() == 1 ? (lhs < rhs.s[0]) : !rhs.s.empty();
410 }
411 bool operator == (int lhs, const UnsignedBigInt& rhs) {
412     return rhs == lhs;
413 }
414 bool operator <= (int lhs, const UnsignedBigInt& rhs) {
415     return lhs < rhs || lhs == rhs;
416 }
417 bool operator > (int lhs, const UnsignedBigInt& rhs) {
418     return !(lhs <= rhs);
419 }
420 bool operator >= (int lhs, const UnsignedBigInt& rhs) {
421     return !(lhs < rhs);
422 }
423 bool operator != (int lhs, const UnsignedBigInt& rhs) {
424     return !(lhs == rhs);
425 }
426
427 UnsignedBigInt sqrt(const UnsignedBigInt& x, int m) {
428     UnsignedBigInt x0;
429     int n = x.s.size();
430
431     if(m <= 1) {
432         assert(m >= 0);
433         if(1 == m)
434             x0 = x;
435     } else if(n <= m) {
436         int L = 0, R = x.BASE - 1, mid;
437         while(L < R) {
438             mid = L + ((R - L + 1) >> 1);
439             if((UnsignedBigInt(mid) ^ m) <= x)
440                 L = mid;
441             else
442                 R = mid - 1;
443         }
444         x0.s.push_back(L);
445     } else if(n <= (m << 1)) {
446         x0.s.resize(2, 0);
447         int L = 0, R = x.BASE - 1, mid;
448         while(L < R) {
449             mid = L + ((R - L + 1) >> 1);
450             x0.s[1] = mid;
451             if((x0 ^ m) <= x)
452                 L = mid;
453             else
454                 R = mid - 1;
455         }
456         x0.s[1] = L;
457         L = 0, R = x.BASE - 1;
458         while(L < R) {
459             mid = L + ((R - L + 1) >> 1);
460             x0.s[0] = mid;
461             if((x0 ^ m) <= x)
462                 L = mid;
463             else
464                 R = mid - 1;
465         }
466         x0.s[0] = L;
467     } else {
468         int mov=(n/m) >> 1;//??????????????
469         x0.s.assign(x.s.begin()+mov*m,x.s.end());
470         x0=(sqrt(x0, m)+1).Move_left_BASE(mov);//+1,?????????
471         UnsignedBigInt x1;
472         do {
473             x1= ((m-1)*x0+x/(x0^(m-1)))/m;
474             swap(x0, x1);
475         } while(x0 < x1);
476         swap(x0, x1);
477     } return x0;
478 }
479
480 ostream& operator << (ostream& out, const UnsignedBigInt& a) {
481     return out << (string)a;
482 }
483
484 istream& operator >> (istream& in, UnsignedBigInt& a) {
485     string str;
486     if(in >> str)
487         a = str;
488     return in;
489 }
490 UnsignedBigInt Quickpow(int t) {
491     UnsignedBigInt Now(2),ans(1);
492     int n=t;
493     while(n) {
494         if(n&1) ans=ans*Now;
495         Now=Now*Now;
496         n>>=1;
497     } return ans;
498 }
499 int n,m;
500 UnsignedBigInt a[N][N],ans,Ans[N],f[N][N][N][2];
501 int main() {
502     scanf("%d%d",&n,&m);
503     for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) cin>>a[i][j];
504     for(int i=1; i<=n; ++i) { //
505         for(int t=1; t<=m; ++t) {//次数
506             for(int j=1; j<=m; ++j) {
507                 if(min(j,m-j+1)>t) continue;
508                 UnsignedBigInt temp=Quickpow(t)*a[i][j];
509                 if(t>=j) {
510                     UnsignedBigInt Now=f[t-1][i][j-1][0]+temp;
511                     if(f[t][i][j][0]<Now) f[t][i][j][0]=Now;
512                     if(m-(t-j)+1>j) {
513                         Now=f[t-1][i][m-(t-j)+1][1]+temp;
514                         if(f[t][i][j][0]<Now) f[t][i][j][0]=Now;
515                     }
516                 }
517                 if(t>=m-j+1) {
518                     UnsignedBigInt Now=f[t-1][i][j+1][1]+temp;
519                     if(f[t][i][j][1]<Now) f[t][i][j][1]=Now;
520                     if(t-(m-j)-1<j) {
521                         Now=f[t-1][i][t-(m-j)-1][0]+temp;
522                         if(f[t][i][j][1]<Now) f[t][i][j][1]=Now;
523                     }
524                 }
525             }
526         }
527         for(int j=1; j<=m; ++j) {
528             if(Ans[i]<f[m][i][j][0]) Ans[i]=f[m][i][j][0];
529             if(Ans[i]<f[m][i][j][1]) Ans[i]=f[m][i][j][1];
530         } ans=ans+Ans[i];
531     } cout<<ans;
532     return 0;
533 }
View Code
02-11 00:10