题目是洛谷 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 }