一些日常工具集合(C++代码片段)
一些日常工具集合(C++代码片段)
在此之前依然要保证算法的正确性以及代码的可写性
本文依然会持久更新,因为一次写不完
目的是自用,如果有错误请指出,万分感谢!
Tools1:算法
这个的重要性就不强调了,轻则多$log$,重则爆$n^2$,更令人窒息者为多项式和非多项式的区别
设计一个好的算法,首先不要想着如何去用$O(n^2)$碾压$O(n)$,而是先想如何实现$O(n)$才是比较好的
洛咕日报15期(霸占评论区三天2333),关于基数排序的
Tools2:IO
IO输出要么没有显著优化,要么直接从TLE优化到AC,在另一篇博客有介绍https://www.cnblogs.com/CreeperLKF/p/8448568.html
然后下面放上一些我平时用的贴在代码前面且具有不同功能的一些东西:
1. 短一些,只有一个小的工具包,没有使用要求
1 #include <cstdio> 2 #include <cctype> 3 #include <cstring> 4 5 //User's Lib 6 7 using namespace std; 8 9 char buf[11111111], *pc = buf; 10 11 struct Main_Guard{ 12 Main_Guard(){ 13 fread(buf, 1, 11111111, stdin); 14 } 15 Main_Guard(const char *ins){ 16 freopen(ins, "r", stdin); 17 fread(buf, 1, 11111111, stdin); 18 } 19 Main_Guard(const char *ins, const char *ous){ 20 freopen(ins, "r", stdin); 21 freopen(ous, "w", stdout); 22 fread(buf, 1, 11111111, stdin); 23 } 24 ~ Main_Guard(){ 25 fclose(stdin), fclose(stdout); 26 } 27 }; 28 29 static inline int read(){ 30 int num = 0; 31 char c, sf = 1; 32 while(isspace(c = *pc++)); 33 if(c == 45) sf = -1, c = *pc ++; 34 while(num = num * 10 + c - 48, isdigit(c = *pc++)); 35 return num * sf; 36 } 37 38 namespace LKF{ 39 template <typename T> 40 extern inline T abs(T tar){ 41 return tar < 0 ? -tar : tar; 42 } 43 template <typename T> 44 extern inline void swap(T &a, T &b){ 45 T t = a; 46 a = b; 47 b = t; 48 } 49 template <typename T> 50 extern inline void upmax(T &x, const T &y){ 51 if(x < y) x = y; 52 } 53 template <typename T> 54 extern inline void upmin(T &x, const T &y){ 55 if(x > y) x = y; 56 } 57 template <typename T> 58 extern inline T max(T a, T b){ 59 return a > b ? a : b; 60 } 61 template <typename T> 62 extern inline T min(T a, T b){ 63 return a < b ? a : b; 64 } 65 } 66 67 //Source Code
2. 长一些,分类讨论一些开关,然后不是所有东西保证效率,功能多
1 //Created By Creeper_LKF 2 //Caution::We used "pragma" in the code 3 #include <cstdio> 4 #include <cctype> 5 #include <cassert> 6 #include <cstdlib> 7 #include <cstring> 8 #include <iostream> 9 10 #ifdef __gnu_linux__ 11 12 #include <fcntl.h> 13 #include <unistd.h> 14 #include <sys/mman.h> 15 16 #endif 17 18 #if __cplusplus < 201103L 19 20 #include <stdarg.h> 21 22 #endif 23 24 //Algorithm Heads 25 26 27 using namespace std; 28 29 //Debug Port 30 31 // #define DEBUG_PORT 32 #define DEBUG 33 34 #ifdef ONLINE_JUDGE 35 #undef DEBUG_PORT 36 #undef DEBUG 37 #endif 38 39 #ifdef DEBUG_PORT 40 #if __cplusplus >= 201103L 41 #ifdef DEBUG 42 template<typename T> 43 extern inline void Debug(T tar){ 44 cerr << tar << endl; 45 } 46 template<typename Head, typename T, typename... Tail> 47 extern inline void Debug(Head head, T mid, Tail... tail){ 48 cerr << head << ' '; 49 Debug(mid, tail...); 50 } 51 #else 52 template<typename Head, typename T, typename... Tail> 53 extern inline void Debug(Head, T, Tail...){ 54 return ; 55 } 56 #endif 57 #else 58 # pragma message "Warning : C++11 Not Use" 59 #ifdef DEBUG 60 template <typename T> 61 extern inline void Debug(T tar){ 62 cerr << tar << endl; 63 } 64 #else 65 template <typename T> 66 extern inline void Debug(T){ 67 return ; 68 } 69 #endif 70 #endif 71 #else 72 template<typename Head, typename T, typename... Tail> 73 extern inline void Debug(Head, T, Tail...){ 74 return ; 75 } 76 template <typename T> 77 extern inline void Debug(T){ 78 return ; 79 } 80 #endif 81 82 const char file_name[] = "b"; 83 84 #define NAME_SPACE 85 #define USING 86 87 #ifdef NAME_SPACE 88 namespace LKF{ 89 #endif 90 #define SF_READ 91 #define EOF_READ 92 // #define ONLINE_JUDGE 93 #define WRITE_ENDL 94 // #define FAST_WRITE 95 #define SPLIT_WRITE 96 const size_t MAX_BUF_SIZE = 50000000; 97 98 #define NEED_FILE 99 100 #ifdef FAST_WRITE 101 char outp[MAX_BUF_SIZE], *op = outp; 102 #endif 103 104 #ifdef ONLINE_JUDGE 105 #undef NEED_FILE 106 #endif 107 108 #ifdef FAST_WRITE 109 #ifndef WRITE_ENDL 110 #define WRITE_ENDL 111 #endif 112 #endif 113 114 extern inline void FILE_OPT(){ 115 #ifdef NEED_FILE 116 #define FILE_NAME file_name 117 char IN_FILE[sizeof(FILE_NAME) + 5], OUT_FILE[sizeof(FILE_NAME) + 5]; 118 strcpy(IN_FILE, FILE_NAME), strcpy(OUT_FILE, FILE_NAME); 119 strcat(IN_FILE, ".in"), strcat(OUT_FILE, ".out"); 120 freopen(IN_FILE, "r", stdin); 121 freopen(OUT_FILE, "w", stdout); 122 #endif 123 } 124 125 #ifdef __gnu_linux__ 126 127 char *pc; 128 129 struct Main_Guard{ 130 Main_Guard(){ 131 #ifndef ONLINE_JUDGE 132 FILE_OPT(); 133 pc = (char *) mmap(NULL, lseek(0, 0, SEEK_END), PROT_READ, MAP_PRIVATE, 0, 0); 134 #endif 135 } 136 ~ Main_Guard(){ 137 #ifdef FAST_WRITE 138 fwrite(outp, 1, op - outp, stdout); 139 #endif 140 fclose(stdin), fclose(stdout); 141 } 142 }; 143 144 #else 145 146 char buf[MAX_BUF_SIZE], *pc = buf; 147 148 struct Main_Guard{ 149 Main_Guard(){ 150 FILE_OPT(); 151 fread(buf, 1, MAX_BUF_SIZE, stdin); 152 } 153 ~ Main_Guard(){ 154 #ifdef FAST_WRITE 155 fwrite(outp, 1, op - outp, stdout); 156 #endif 157 fclose(stdin), fclose(stdout); 158 } 159 }; 160 161 #endif 162 163 inline char read_ch(){ 164 char c; 165 while(isspace(c = *pc ++)); 166 return c; 167 } 168 169 #ifdef EOF_READ 170 171 #ifdef SF_READ 172 173 template<typename T> 174 static inline void read(T &num){ 175 num = 0; 176 char c, sf = 1; 177 while(isspace(c = *pc++)); 178 if(c == 45) sf = -1, c = *pc ++; 179 while(num = num * 10 + c - 48, isdigit(c = *pc++)); 180 num *= sf; 181 } 182 183 static inline int read(){ 184 int num = 0; 185 char c, sf = 1; 186 while(isspace(c = *pc++)); 187 if(c == 45) sf = -1, c = *pc ++; 188 while(num = num * 10 + c - 48, isdigit(c = *pc++)); 189 return num * sf; 190 } 191 192 static inline double read_dec(){ 193 double num = 0, decs = 1; 194 char c, sf = 1; 195 while(isspace(c = *pc ++)); 196 if(c == '-') sf = -1, c = *pc ++; 197 while(num = num * 10 + c - 48, isdigit(c = *pc ++)); 198 if(c != '.') return num * sf; 199 c = *pc ++; 200 while(num += (decs *= 0.1) * (c - 48), isdigit(c = *pc ++)); 201 return num * sf; 202 } 203 204 #else 205 206 template<typename T> 207 static inline T read(T &num){ 208 num = 0; 209 char c; 210 while (isspace(c = *pc++)); 211 while (num = num * 10 + c - 48, isdigit(c = *pc++)); 212 return num; 213 } 214 215 static inline int read(){ 216 int num = 0; 217 char c; 218 while (isspace(c = *pc++)); 219 while (num = num * 10 + c - 48, isdigit(c = *pc++)); 220 return num; 221 } 222 223 static inline double read_dec(){ 224 double num = 0, decs = 1; 225 char c; 226 while(isspace(c = *pc ++)); 227 while(num = num * 10 + c - 48, isdigit(c = *pc ++)); 228 if(c != '.') return num; 229 c = *pc ++; 230 while(num += (c - 48) * (decs *= 0.1), isdigit(c = *pc ++)); 231 return num; 232 } 233 234 #endif 235 236 #else 237 238 #ifdef SF_READ 239 240 template<typename T> 241 static inline void read(T &num){ 242 num = 0; 243 char c, sf = 1; 244 while((c = *pc++) < 45); 245 if(c == 45) sf = -1, c = *pc ++; 246 while(num = num * 10 + c - 48, (c = *pc++) >= 48); 247 num *= sf; 248 } 249 250 static inline int read(){ 251 int num = 0; 252 char c, sf = 1; 253 while((c = *pc++) < 45); 254 if(c == 45) sf = -1, c = *pc ++; 255 while(num = num * 10 + c - 48, (c = *pc++) >= 48); 256 return num * sf; 257 } 258 259 static inline double read_dec(){ 260 double num = 0, decs = 1; 261 char c, sf = 1; 262 while(isspace(c = *pc ++)); 263 if(c == '-') sf = -1, c = *pc ++; 264 while(num = num * 10 + c - 48, isdigit(c = *pc ++)); 265 if(c != '.') return num * sf; 266 c = *pc ++; 267 while(num += (decs *= 0.1) * (c - 48), isdigit(c = *pc ++)); 268 return num * sf; 269 } 270 271 #else 272 273 template<typename T> 274 static inline T read(T &num){ 275 num = 0; 276 char c; 277 while ((c = *pc++) < 48); 278 while (num = num * 10 + c - 48, (c = *pc++) >= 48); 279 return num; 280 } 281 282 static inline int read(){ 283 int num = 0; 284 char c; 285 while ((c = *pc++) < 48); 286 while (num = num * 10 + c - 48, (c = *pc++) >= 48); 287 return num; 288 } 289 290 static inline double read_dec(){ 291 double num = 0, decs = 1; 292 char c; 293 while(isspace(c = *pc ++)); 294 while(num = num * 10 + c - 48, isdigit(c = *pc ++)); 295 if(c != '.') return num; 296 c = *pc ++; 297 while(num += (c - 48) * (decs *= 0.1), isdigit(c = *pc ++)); 298 return num; 299 } 300 301 #endif 302 303 #endif 304 305 #ifdef FAST_WRITE 306 template <typename T> 307 inline void Call_Write(char Split, T tar){ 308 char buf[20]; 309 int top = 0; 310 if(tar == 0) *op ++ = 48; 311 else { 312 if(tar < 0) *op ++ = '-', tar = -tar; 313 while(tar) buf[++top] = tar % 10, tar /= 10; 314 while(top) *op ++ = buf[top --] ^ 48; 315 } 316 *op ++ = Split; 317 } 318 template <typename T> 319 inline void Call_Write(T tar){ 320 char buf[20]; 321 int top = 0; 322 if(tar == 0) *op ++ = 48; 323 else { 324 if(tar < 0) *op ++ = '-', tar = -tar; 325 while(tar) buf[++top] = tar % 10, tar /= 10; 326 while(top) *op ++ = buf[top --] ^ 48; 327 } 328 } 329 #endif 330 331 #ifdef FAST_WRITE 332 333 extern inline void write(){ 334 *op ++ = '\n'; 335 } 336 337 template<typename T> 338 extern inline void write(T tar){ 339 Call_Write(tar); 340 #ifdef WRITE_ENDL 341 write(); 342 #endif 343 } 344 345 #if __cplusplus >= 201103L 346 347 template<typename T> 348 extern inline void write(char, T tar){ 349 Call_Write(tar); 350 #ifdef WRITE_ENDL 351 write(); 352 #endif 353 } 354 355 template<typename Head, typename T, typename... Tail> 356 extern inline void write(char Split, Head head, T mid, Tail... tail){ 357 Call_Write(Split, head); 358 write(Split, mid, tail...); 359 } 360 361 #else 362 363 template <typename T> 364 extern inline void write(char Split, T tar){ 365 Call_Write(tar); 366 #ifdef WRITE_ENDL 367 write(); 368 #endif 369 } 370 371 #endif 372 373 #else 374 375 extern inline void write(){ 376 cout << endl; 377 } 378 379 template<typename T> 380 extern inline void write(T tar){ 381 cout << tar; 382 #ifdef WRITE_ENDL 383 write(); 384 #endif 385 } 386 387 #if __cplusplus >= 201103L 388 389 template<typename T> 390 extern inline void write(char Split, T tar){ 391 cout << tar << Split; 392 #ifdef WRITE_ENDL 393 write(); 394 #endif 395 } 396 397 template<typename Head, typename T, typename... Tail> 398 extern inline void write(char Split, Head head, T mid, Tail... tail){ 399 #ifdef SPLIT_WRITE 400 cout << head << Split; 401 #else 402 cout << head; 403 #endif 404 write(Split, mid, tail...); 405 } 406 407 #else 408 409 template <typename T> 410 extern inline void write(char Split, T tar){ 411 cout << tar << Split; 412 #ifdef WRITE_ENDL 413 write(); 414 #endif 415 } 416 417 #endif 418 419 #endif 420 421 template <typename T> 422 extern inline void upmax(T &x, const T &y){ 423 if(x < y) x = y; 424 } 425 template <typename T> 426 extern inline void upmin(T &x, const T &y){ 427 if(x > y) x = y; 428 } 429 430 #if __cplusplus >= 201103L 431 432 template<typename T> 433 extern inline T max(T tar){ 434 return tar; 435 } 436 437 template<typename T> 438 extern inline T min(T tar){ 439 return tar; 440 } 441 442 template <typename Head, typename T, typename... Tail> 443 extern inline Head max(Head head, T mid, Tail... tail){ 444 Head tmp = max(mid, tail...); 445 return head > tmp ? head : tmp; 446 } 447 template <typename Head, typename T, typename... Tail> 448 extern inline Head min(Head head, T mid, Tail... tail){ 449 Head tmp = min(mid, tail...); 450 return head < tmp ? head : tmp; 451 } 452 453 #else 454 455 template <typename T> 456 extern inline T max(T a, T b){ 457 return a > b ? a : b; 458 } 459 template <typename T> 460 extern inline T min(T a, T b){ 461 return a < b ? a : b; 462 } 463 464 #endif 465 466 template <typename T> 467 extern inline T abs(T tar){ 468 return tar < 0 ? -tar : tar; 469 } 470 template <typename T> 471 extern inline void swap(T &a, T &b){ 472 T t = a; 473 a = b; 474 b = t; 475 } 476 #ifdef NAME_SPACE 477 } 478 #endif 479 480 //Algorithm 481 482 #ifdef NAME_SPACE 483 namespace LKF{ 484 #endif 485 486 template <class Tn, size_t ArraySize> 487 struct Queue{ 488 size_t s, t; 489 Tn q[ArraySize]; 490 Queue(){ 491 s = 1, t = 0; 492 } 493 inline void clear(){ 494 s = 1, t = 0; 495 } 496 inline bool empty(){ 497 return s > t; 498 } 499 inline size_t size(){ 500 return t - s + 1; 501 } 502 inline void push(Tn tar){ 503 q[++ t] = tar; 504 } 505 inline void pop_front(){ 506 s ++; 507 } 508 inline void pop_back(){ 509 t --; 510 } 511 inline Tn front(){ 512 return q[s]; 513 } 514 inline Tn back(){ 515 return q[t]; 516 } 517 }; 518 519 template <class Tn, size_t ArraySize> 520 struct Stack{ 521 size_t t; 522 Tn s[ArraySize]; 523 Stack(){ 524 t = 0; 525 } 526 inline void clear(){ 527 t = 0; 528 } 529 inline bool empty(){ 530 return t == 0; 531 } 532 inline size_t size(){ 533 return t; 534 } 535 inline void push(Tn tar){ 536 s[++ t] = tar; 537 } 538 inline Tn top(){ 539 return s[t]; 540 } 541 inline void pop(){ 542 t --; 543 } 544 }; 545 546 #ifdef NAME_SPACE 547 } 548 #endif 549 550 #ifdef USING 551 552 #ifdef NAME_SPACE 553 using LKF::pc; 554 using LKF::read_ch; 555 using LKF::read_dec; 556 using LKF::read; 557 using LKF::write; 558 using LKF::upmax; 559 using LKF::upmin; 560 using LKF::max; 561 using LKF::min; 562 using LKF::abs; 563 // using LKF::swap; 564 #else 565 using ::pc; 566 using ::read_ch; 567 using ::read_dec; 568 using ::read; 569 using ::write; 570 using ::upmax; 571 using ::upmin; 572 using ::max; 573 using ::min; 574 using ::abs; 575 // using ::swap; 576 #endif 577 578 #endif 579 580 //Source Code
3. C++11下可以使用调试多参数调试 Debug(arg1, arg2...) ,建议搭配dot可以直接图论题中绘图,可以不删除调试代码交到Luogu上
1 #include <cstdio> 2 #include <cctype> 3 #include <cstring> 4 #include <iostream> 5 6 //User's Lib 7 8 using namespace std; 9 10 // #define DEBUG_PORT 11 #define DEBUG 12 13 #ifdef ONLINE_JUDGE 14 #undef DEBUG_PORT 15 #undef DEBUG 16 #endif 17 18 #ifdef DEBUG_PORT 19 #if __cplusplus >= 201103L 20 #ifdef DEBUG 21 template<typename T> 22 extern inline void Debug(T tar){ 23 cerr << tar << endl; 24 } 25 template<typename Head, typename T, typename... Tail> 26 extern inline void Debug(Head head, T mid, Tail... tail){ 27 cerr << head << ' '; 28 Debug(mid, tail...); 29 } 30 #else 31 template<typename Head, typename T, typename... Tail> 32 extern inline void Debug(Head, T, Tail...){ 33 return ; 34 } 35 #endif 36 #else 37 # pragma message "Warning : C++11 Not Use" 38 #ifdef DEBUG 39 template <typename T> 40 extern inline void Debug(T tar){ 41 cerr << tar << endl; 42 } 43 #else 44 template <typename T> 45 extern inline void Debug(T){ 46 return ; 47 } 48 #endif 49 #endif 50 #else 51 template<typename Head, typename T, typename... Tail> 52 extern inline void Debug(Head, T, Tail...){ 53 return ; 54 } 55 template <typename T> 56 extern inline void Debug(T){ 57 return ; 58 } 59 #endif 60 61 char buf[11111111], *pc = buf; 62 63 struct Main_Guard{ 64 Main_Guard(){ 65 fread(buf, 1, 11111111, stdin); 66 } 67 Main_Guard(const char *ins){ 68 freopen(ins, "r", stdin); 69 fread(buf, 1, 11111111, stdin); 70 } 71 Main_Guard(const char *ins, const char *ous){ 72 freopen(ins, "r", stdin); 73 freopen(ous, "w", stdout); 74 fread(buf, 1, 11111111, stdin); 75 } 76 ~ Main_Guard(){ 77 fclose(stdin), fclose(stdout); 78 } 79 }; 80 81 static inline int read(){ 82 int num = 0; 83 char c, sf = 1; 84 while(isspace(c = *pc++)); 85 if(c == 45) sf = -1, c = *pc ++; 86 while(num = num * 10 + c - 48, isdigit(c = *pc++)); 87 return num * sf; 88 } 89 90 namespace LKF{ 91 template <typename T> 92 extern inline T abs(T tar){ 93 return tar < 0 ? -tar : tar; 94 } 95 template <typename T> 96 extern inline void swap(T &a, T &b){ 97 T t = a; 98 a = b; 99 b = t; 100 } 101 template <typename T> 102 extern inline void upmax(T &x, const T &y){ 103 if(x < y) x = y; 104 } 105 template <typename T> 106 extern inline void upmin(T &x, const T &y){ 107 if(x > y) x = y; 108 } 109 template <typename T> 110 extern inline T max(T a, T b){ 111 return a > b ? a : b; 112 } 113 template <typename T> 114 extern inline T min(T a, T b){ 115 return a < b ? a : b; 116 } 117 } 118 119 //Source Code
4. 只能读非负整数,然后用的是更快的读入,但是在本地都开了文件输入输出
1 #include <cstdio> 2 3 #include <fcntl.h> 4 #include <unistd.h> 5 #include <sys/mman.h> 6 7 //User's Lib 8 9 using namespace std; 10 11 char *pc; 12 13 char outp[1111111], *op = outp; 14 15 struct Main_Guard{ 16 Main_Guard(){ 17 pc = (char *) mmap(NULL, lseek(0, 0, SEEK_END), PROT_READ, MAP_PRIVATE, 0, 0); 18 } 19 Main_Guard(const char *ins){ 20 freopen(ins, "r", stdin); 21 pc = (char *) mmap(NULL, lseek(0, 0, SEEK_END), PROT_READ, MAP_PRIVATE, 0, 0); 22 } 23 Main_Guard(const char *ins, const char *ous){ 24 freopen(ins, "r", stdin); 25 freopen(ous, "w", stdout); 26 pc = (char *) mmap(NULL, lseek(0, 0, SEEK_END), PROT_READ, MAP_PRIVATE, 0, 0); 27 } 28 ~ Main_Guard(){ 29 fwrite(outp, 1, op - outp, stdout); 30 fclose(stdin), fclose(stdout); 31 } 32 }; 33 34 inline int read(){ 35 int num = 0; 36 char c; 37 while((c = *pc ++) < 48); 38 while(num = num * 10 + c - 48, (c = *pc ++) >= 48); 39 return num; 40 } 41 42 inline void Write(const char *tar){ 43 for(register int i = 0, lim = strlen(tar); i < lim; i++) 44 *op ++ = tar[i]; 45 } 46 47 inline void Write(const int &tar){//You Need To Write '-' and '\n' By Hand 48 if(!tar) return ; 49 Write(tar / 10); 50 *op ++ = (tar % 10) ^ 48; 51 } 52 53 namespace LKF{ 54 template <typename T> 55 extern inline T abs(T tar){ 56 return tar < 0 ? -tar : tar; 57 } 58 template <typename T> 59 extern inline void swap(T &a, T &b){ 60 T t = a; 61 a = b; 62 b = t; 63 } 64 template <typename T> 65 extern inline void upmax(T &x, const T &y){ 66 if(x < y) x = y; 67 } 68 template <typename T> 69 extern inline void upmin(T &x, const T &y){ 70 if(x > y) x = y; 71 } 72 template <typename T> 73 extern inline T max(T a, T b){ 74 return a > b ? a : b; 75 } 76 template <typename T> 77 extern inline T min(T a, T b){ 78 return a < b ? a : b; 79 } 80 } 81 82 //Source Code
5. C++11特性用,删掉了分类讨论
1 #include <cstdio> 2 #include <cctype> 3 #include <cstring> 4 #include <iostream> 5 6 //User's Lib 7 8 using namespace std; 9 10 #define DEBUG 11 12 #ifdef ONLINE_JUDGE 13 #undef DEBUG 14 #endif 15 16 #ifdef DEBUG 17 template<typename T> 18 extern inline void Debug(T tar){ 19 cerr << tar << endl; 20 } 21 template<typename Head, typename T, typename... Tail> 22 extern inline void Debug(Head head, T mid, Tail... tail){ 23 cerr << head << ' '; 24 Debug(mid, tail...); 25 } 26 #else 27 template<typename Head, typename T, typename... Tail> 28 extern inline void Debug(Head, T, Tail...){ 29 return ; 30 } 31 #endif 32 33 char buf[11111111], *pc = buf; 34 35 struct Main_Guard{ 36 Main_Guard(){ 37 fread(buf, 1, 11111111, stdin); 38 } 39 Main_Guard(const char *ins){ 40 freopen(ins, "r", stdin); 41 fread(buf, 1, 11111111, stdin); 42 } 43 Main_Guard(const char *ins, const char *ous){ 44 freopen(ins, "r", stdin); 45 freopen(ous, "w", stdout); 46 fread(buf, 1, 11111111, stdin); 47 } 48 ~ Main_Guard(){ 49 fclose(stdin), fclose(stdout); 50 } 51 }; 52 53 static inline int read(){ 54 int num = 0; 55 char c, sf = 1; 56 while(isspace(c = *pc++)); 57 if(c == 45) sf = -1, c = *pc ++; 58 while(num = num * 10 + c - 48, isdigit(c = *pc++)); 59 return num * sf; 60 } 61 62 namespace LKF{ 63 template <typename T> 64 extern inline void upmax(T &x, const T &y){ 65 if(x < y) x = y; 66 } 67 template <typename T> 68 extern inline void upmin(T &x, const T &y){ 69 if(x > y) x = y; 70 } 71 72 template<typename T> 73 extern inline T max(T tar){ 74 return tar; 75 } 76 77 template<typename T> 78 extern inline T min(T tar){ 79 return tar; 80 } 81 82 template <typename Head, typename T, typename... Tail> 83 extern inline Head max(Head head, T mid, Tail... tail){ 84 Head tmp = max(mid, tail...); 85 return head > tmp ? head : tmp; 86 } 87 template <typename Head, typename T, typename... Tail> 88 extern inline Head min(Head head, T mid, Tail... tail){ 89 Head tmp = min(mid, tail...); 90 return head < tmp ? head : tmp; 91 } 92 93 template <typename T> 94 extern inline T abs(T tar){ 95 return tar < 0 ? -tar : tar; 96 } 97 template <typename T> 98 extern inline void swap(T &a, T &b){ 99 T t = a; 100 a = b; 101 b = t; 102 } 103 } 104 105 //Source Code
6. 最简单的快读
1 #include <cstdio> 2 3 using namespace std; 4 5 char buf[11111111], *pc = buf; 6 7 struct Main_Guard{ 8 Main_Guard(){ 9 fread(buf, 1, 11111111, stdin); 10 } 11 Main_Guard(const char *ins){ 12 freopen(ins, "r", stdin); 13 fread(buf, 1, 11111111, stdin); 14 } 15 Main_Guard(const char *ins, const char *ous){ 16 freopen(ins, "r", stdin); 17 freopen(ous, "w", stdout); 18 fread(buf, 1, 11111111, stdin); 19 } 20 ~ Main_Guard(){ 21 fclose(stdin), fclose(stdout); 22 } 23 }; 24 25 inline int read(){ 26 int num = 0; 27 char c; 28 while((c = *pc ++) < 48); 29 while(num = num * 10 + c - 48, (c = *pc ++) >= 48); 30 return num; 31 } 32 33 //Source Code
由于最近改了一下,所以可能还会有一点Bug
Main_Guard调用方法就是在main函数开头写 Main_Guard main_guard; 如果需要读入的话就在后面带括号和文件名,输出的话就带两个字符串
这样的好处就是一定会调用析构函数
Tools3:__builtin_
一个非常妙而且实用的工具,有些C++库函数会调用到,不过自己去学会调用肯定会比较妙,整个Builtin家族非常大(看文档https://gcc.gnu.org/onlinedocs/gcc/,具体可以在https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins查找),这里只介绍一些常用的。下面的函数的参数以及返回值对照了gcc文档。
二进制相关
(注意下面函数定义在unsigned int(或int)上,如果需要使用unsigned long long(或long long)版则可以在函数名后面加上ll,例如__builtin_ffsll接受long long的参数)。
- int __builtin_ffs (int x) :查询x二进制最后一个1是第几位
- int __builtin_clz (unsigned int x) :查询x有多少个前导0,If x is 0, the result is undefined.
- int __builtin_ctz (unsigned int x) :查询x有多少个后缀0,If x is 0, the result is undefined.
- int __builtin_popcount (unsigned int x) :查询x有多少个1,在洛谷日爆未来的某期内我还了解到了还可以加#pragma GCC target ("popcnt")直接把这玩意转化成指令加速,优化效果高达70%(网上某些题的实验)
- int __builtin_parity (unsigned int x) :查询x的二进制奇偶校验,也就是x中1的个数模2
- uint16_t __builtin_bswap16 (uint16_t x) :按照字节翻转二进制位,例如0xaabb翻转成为0xbbaa,然后16可替换为32,64,表示位数
- int __builtin_clrsb (int x) :查询x有多少个和符号位相同的前导二进制位(不统计符号位)
CPU分支预测优化
long __builtin_expect (long exp, long c)
函数的作用就是引导CPU在分支预测的时候选择某个if分支执行,以前靠这个东西直接把一道题卡到了0ms,单点甩Rank2接近8ms,可见有些情况下效果还是不错的
食用方法:exp那里填写你希望预测的一个表达式,建议不要写的太复杂了,c填写你预测表达式大概率会是什么值,然后直接用在if内即可,例如 if(__builtin_expect(a === b, 0))
效果:如果写的比较好的话有一些大优化,否则会导致CPU频繁罚时
例子:例如你知道某个数据结构它的体型庞大而且你有特意地防止node指针指向NULL,但是如果你不放心的话那么可以加一个这个。例如表达式$i%100000000==1$一般会比较难成立,可以优化,而$i%10==1$就不需要这样优化了
提前写入缓存
void __builtin_prefetch (const void *addr, ...)
就是提前把数据取到缓存
gcc的参数表最后面还有两个可选参数,rw和locality,表示使用这个数据是读或者写(1是写0是读),以及这个数据的时间局部性。
读或者写就不说了
时间局部性表示这个数据在被访问之后在一定时间内还会不会再次访问(而不是距离第一次访问还有多久),决定了这个数据在缓存中的“寿命”。0表示没有时间局部性,也就是很长时间内不再访问,而3表示高时间局部性,表示访问了时候很快又会访问。这个参数一定是个编译时候的常量,默认为3.
Tools4:细节
首先register和inline标记应该都会吧。register表示建议编译器将变量放在编译器中,C++11及以上为了防止滥用渐渐开始忽略这个东西,在C++17时你会被提醒这个东西已经不能用了。inline在我讲快读那篇文章的末尾有https://www.cnblogs.com/CreeperLKF/p/8448568.html
例如下面Luogu上两份A+B Problem(找LZL123测试的),代码相差无几,但是时间差了584ms,空间差了63971kb,差距竟然只有1000的数据范围
见提交记录https://www.luogu.org/record/show?rid=6205849和https://www.luogu.org/recordnew/show/5650350
代码区别:
584ms:
1 #include <cstdio> 2 int x[1<<24]; 3 int main() 4 { 5 int a,b,ans=0; 6 for(int i=1;i<=1<<24;++i) 7 x[i]++,ans+=x[i]; 8 scanf("%d%d",&a,&b); 9 printf("%d",a+b); 10 return 0; 11 }
0ms:
1 #include <cstdio> 2 int x[1<<24+1000]; 3 int main() 4 { 5 int a,b,ans=0; 6 for(int i=1;i<=1<<24+1000;++i) 7 x[i]++,ans+=x[i]; 8 scanf("%d%d",&a,&b); 9 printf("%d",a+b); 10 return 0; 11 }
关于register:这种东西比较奇怪,现代CPU确实先进了不少,但是某些OJ上是有效的,例如提交记录
可能存在干扰因素,有兴趣的可以自己去各大OJ调查一下(例如上次我在HDU加了优化之后还变慢了)
Tools5:强力Random工具
这个Random工具就是用mt19937(C++ Reference Wiki)加上Linux下的/dev/random和/dev/urandom以及某种非常高精度的时钟实现的,速度可观,可以在Windows下运行
然后测试效果海星,其中的宏也已经定义好,开袋即食,您的造数据好帮手
注意如果要大量生成数据的话不要使用/dev/random,否则会比较卡(如果必须的话你可以手动调节一下中间的Init_Rand_Buf)
注意某些函数可能会被成功inline,调试的时候如果发现这个函数“没有调用”不要慌
持续更新QWQ
下面放一个新版本,2021-05-25更新,用于IGCA的(老版本在后面,但是已知存在问题),以后再整理
1 #include <random> 2 #include <algorithm> 3 4 using namespace std; 5 6 /** 7 * 虽然你会发现有些函数不能接收int 8 * 不过这是故意的呢QWQ 9 * 呐呐呐 10 */ 11 struct _Random { 12 13 std::mt19937 Generator; 14 std::mt19937_64 Generator_64; 15 16 _Random(unsigned int seed = 19260817/*std::time(NULL)*/) : 17 Generator(seed), Generator_64(seed) { 18 srand(seed); 19 }; 20 21 inline unsigned rand(); 22 inline unsigned rand_64(); 23 inline unsigned rand(const unsigned& up); ///< [0, up) 24 inline unsigned long long rand(const unsigned long long& up); ///< [0, up) 25 inline unsigned randInt(const unsigned& up); ///< [1, up] 26 inline unsigned long long randInt(const unsigned long long& up); ///< [1, up] 27 inline unsigned randInt(const unsigned& down, const unsigned& up); ///< [down, up] 28 inline unsigned long long randInt(const unsigned long long& down, const unsigned long long& up); ///< [down, up] 29 inline double randDouble(); ///< [0, 1)均匀 30 inline double randDouble(const double& down, const double& up); ///< [down, up] 31 inline unsigned randBit(); ///< 0 / 1 32 template <typename Iterator_Type> 33 inline void randomShuffle(Iterator_Type __first, Iterator_Type __last); 34 template <typename Iterator_Type> 35 inline Iterator_Type randomPicker(Iterator_Type __first, Iterator_Type __last); 36 }; 37 38 inline unsigned _Random::rand() { 39 return Generator(); 40 } 41 42 inline unsigned _Random::rand_64() { 43 return Generator_64(); 44 } 45 46 inline unsigned _Random::rand(const unsigned& up) { 47 return rand() % up; 48 } 49 50 inline unsigned long long _Random::rand(const unsigned long long &up){ 51 return rand_64() % up; 52 } 53 54 inline unsigned _Random::randInt(const unsigned &up) { 55 return rand() % up + 1; 56 } 57 58 inline unsigned long long _Random::randInt(const unsigned long long &up) { 59 return rand_64() % up + 1; 60 } 61 62 unsigned _Random::randInt(const unsigned &down, const unsigned &up) { 63 return rand() % (up - down + 1) + down; 64 } 65 66 unsigned long long _Random::randInt(const unsigned long long &down, const unsigned long long &up) { 67 return rand() % (up - down + 1) + down; 68 } 69 70 double _Random::randDouble() { 71 union { 72 double d; 73 unsigned long long u; 74 }ret; 75 ret.u = (Generator_64() >> 12) | 0x3FF0000000000000ULL; 76 return ret.d - 1.0; 77 } 78 79 double _Random::randDouble(const double& down, const double& up) { 80 return randDouble() * (up - down) + down; 81 } 82 83 unsigned _Random::randBit() { 84 return rand() & 1; 85 } 86 87 template <typename Iterator_Type> 88 void _Random::randomShuffle(Iterator_Type __first, Iterator_Type __last) { 89 random_shuffle(__first, __last, this -> rand); 90 } 91 92 template <typename Iterator_Type> 93 inline Iterator_Type _Random::randomPicker(Iterator_Type __first, Iterator_Type __last){ 94 return __first + this -> rand((unsigned long long)(__last - __first)); 95 } 96 97 _Random Random;
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~Random_Part~~~~~~~~~~~~~~~~~~~~~~~~ 2 3 //食用说明:在一开始需要调用Rand_Initialize 4 //如果需求量和速度要求不高的话可以打开DO_NOT_USE_URANDOM 5 //如果在Linux的话可以打开RAND_BUF 6 //这样可以让随机位取地比较好 7 //呐呐呐 8 9 #include <chrono> 10 #include <random> 11 #include <algorithm> 12 13 #ifdef __gnu_linux__ 14 #define RAND_BUF 15 // #define DO_NOT_USE_URANDOM 16 #endif 17 18 #ifdef RAND_BUF 19 #include <fcntl.h> 20 #include <unistd.h> 21 #include <sys/types.h> 22 #include <sys/stat.h> 23 #endif 24 25 using namespace std; 26 27 mt19937 Generator; 28 29 #define BUF_SIZE 8193 30 31 #ifdef RAND_BUF 32 char rand_buf[BUF_SIZE], *p1 = rand_buf, *p2 = rand_buf; 33 int buf_times, rand_fd; 34 inline void Init_Rand_Buf(){ 35 buf_times ++; 36 if(buf_times < 127) p2 = (p1 = rand_buf) + read(rand_fd, rand_buf, sizeof(rand_buf)); 37 if(buf_times == 127 || p1 + BUF_SIZE != p2){ 38 if(buf_times == 127) buf_times = 0; 39 for(int i = 0; i < BUF_SIZE; i++) rand_buf[i] = Generator(); 40 p2 = (p1 = rand_buf) + BUF_SIZE; 41 } 42 } 43 inline int Rand_Bit(){ 44 if(p1 == p2) Init_Rand_Buf(); 45 return (*p1 ++ & 1); 46 } 47 #endif 48 49 inline void Rand_Initialize(){ 50 unsigned seed1 = chrono::system_clock::now().time_since_epoch().count(); 51 52 #ifdef RAND_BUF 53 #ifdef DO_NOT_USE_URANDOM 54 rand_fd = open("/dev/random", 0); 55 #else 56 rand_fd = open("/dev/urandom", 0); 57 #endif 58 Init_Rand_Buf(); 59 *(-- p2) = seed1 & 0xff; 60 *(-- p2) = (seed1 >> 8) & 0xff; 61 *(-- p2) = (seed1 >> 16) & 0xff; 62 *(-- p2) = (seed1 >> 24) & 0xff; 63 p2 ++, p2 ++, p2 ++, p2 ++; 64 seed_seq seed2(p1, p2); 65 Generator = mt19937(seed2); 66 #else 67 Generator mt19937(seed1); 68 #endif 69 } 70 71 inline unsigned Rand(){ 72 return Generator(); 73 } 74 75 inline unsigned Rand(unsigned up){ 76 return Rand() % up + 1; 77 } 78 79 inline unsigned Rand(unsigned down, unsigned up){ 80 return Rand() % (up - down + 1) + down; 81 } 82 83 inline double Rand_Float(){ 84 return (double)Rand() / (unsigned)0xffffffff; 85 } 86 87 inline unsigned long long Rand_ull(){ 88 return (unsigned long long)Rand() * Rand(); 89 } 90 91 #ifndef RAND_BUF 92 inline int Rand_Bit(){ 93 return Rand() & 1; 94 } 95 #endif 96 97 inline unsigned Rand_Number(unsigned up){ 98 return Rand() % up; 99 } 100 101 template <typename Iterator_Type> 102 inline void Random_Shuffle(Iterator_Type __first, Iterator_Type __last){ 103 random_shuffle(__first, __last, Rand_Number); 104 } 105 106 //~~~~~~~~~~~~~~~~~~~~~~~~~~~Random_Part~~~~~~~~~~~~~~~~~~~~~~~~
Tools6:其他的东西
1 //~~~~~~~~~~~~~~~~~~~~~~~Graph_Code~~~~~~~~~~~~~~~~~~~~ 2 3 template <size_t VS, size_t ES> 4 struct __Graph_Base{ 5 int tot; 6 int beginx[VS], endx[ES], nxt[ES]; 7 __Graph_Base() : tot(1){ 8 memset(beginx, 0, sizeof(beginx)); 9 } 10 inline void clear(){ 11 tot = 1; 12 memset(beginx, 0, sizeof(beginx)); 13 } 14 }; 15 16 template <size_t VS, size_t ES> 17 struct Graph : __Graph_Base<VS, ES>{ 18 19 using __Graph_Base<VS, ES>::tot; 20 using __Graph_Base<VS, ES>::nxt; 21 using __Graph_Base<VS, ES>::beginx; 22 using __Graph_Base<VS, ES>::endx; 23 24 inline void clear(){ 25 __Graph_Base<VS, ES>::clear(); 26 } 27 inline void add_edge(const int &u, const int &v){ 28 nxt[++ tot] = beginx[u], beginx[u] = tot, endx[tot] = v; 29 nxt[++ tot] = beginx[v], beginx[v] = tot, endx[tot] = u; 30 } 31 }; 32 33 //~~~~~~~~~~~~~~~~~~~~~~~Graph_Code~~~~~~~~~~~~~~~~~~~~ 34 35 //~~~~~~~~~~~~~~~~~~~~~~~Matrix_Code~~~~~~~~~~~~~~~~~~~ 36 37 template <size_t Matrix_Size> 38 struct Matrix{ 39 int a[Matrix_Size][Matrix_Size]; 40 41 Matrix(){ 42 memset(a, 0, sizeof(a)); 43 } 44 45 Matrix(const int &tar){ 46 memset(a, 0, sizeof(a)); 47 for(register int i = 1; i <= MAX; i++) 48 a[i][i] = tar; 49 } 50 51 inline int * operator [] (const int &tar){ 52 return a[tar]; 53 } 54 55 inline const int * operator [] (const int &tar) const { 56 return a[tar]; 57 } 58 59 inline Matrix operator * (const Matrix &tar) const { 60 Matrix ret; 61 for(register int i = 1; i <= MAX; i++) 62 for(register int k = 1; k <= MAX; k++) 63 for(register int j = 1; j <= MAX; j++) 64 ret[i][j] += a[i][k] * tar.a[k][j]; 65 return ret; 66 } 67 68 inline Matrix & operator *= (const Matrix &tar){ 69 return *this = (*this) * tar; 70 } 71 72 template <typename T> 73 inline Matrix operator ^ (register T tar) const { 74 Matrix ret(1), tmp = *this; 75 while(tar){ 76 if(tar & 1) ret *= tmp; 77 tmp *= tmp; 78 tar >>= 1; 79 } 80 return ret; 81 } 82 83 template <typename T> 84 inline Matrix & operator ^= (const T &tar){ 85 return *this = (*this) ^ tar; 86 } 87 88 template <typename T> 89 inline Matrix pow(register T tar, Matrix Init_Matrix) const { 90 Matrix ret(1); 91 while(tar){ 92 if(tar & 1) ret *= Init_Matrix; 93 Init_Matrix *= Init_Matrix; 94 tar >>= 1; 95 } 96 return ret; 97 } 98 99 }; 100 101 //~~~~~~~~~~~~~~~~~~~~~~~Matrix_Code~~~~~~~~~~~~~~~~~~~
关于Graph:就是有时候同一道题可能会有很多张图,然后你要调试的话就可以把这个东西写开,然后为每一种图加一个Debug,或者是有时候需要同时维护有向图和无向图
关于Matrix:就不解释了QWQ
Tools7:基数排序(持续更新于此)
1 #include <cstdio> 2 #include <cstring> 3 4 #include <algorithm> 5 6 using namespace std; 7 8 // Source Code 9 10 /* 11 * 食用说明 12 * 前面针对bit的排序除了80Bit的其他的返回的都是a为sorted数组 13 * 后面long double的排序也是交换了一次数组,还有一个不交换的版本 14 * 传进去的参数都是1. 排序范围, 2. 待排序数组, 3. 中间值数组,待排序数组要求数据下标从1开始 15 * 建议把那个通用的Radix_Sort_Bit函数内变换循环顺序后进行循环展开 16 * Radix_Sort_Bit排序只适合于小端法机器 17 */ 18 19 template <typename T> 20 inline void Radix_Sort_32Bit(register const int n, T *a, T *b){ 21 unsigned r1[0x100], r2[0x100], r3[0x100], r4[0x100]; 22 memset(r1, 0, sizeof(r1)), memset(r2, 0, sizeof(r2)); 23 memset(r3, 0, sizeof(r3)), memset(r4, 0, sizeof(r4)); 24 25 register int i; 26 register unsigned int tmp_int; 27 register T * j, *tar; 28 29 for(j = a + 1, tar = a + 1 + n; j != tar; ++j){ 30 tmp_int = * (unsigned int *) j; 31 ++r1[tmp_int & 0xff]; 32 ++r2[(tmp_int >> 0x8) & 0xff]; 33 ++r3[(tmp_int >> 0x10) & 0xff]; 34 ++r4[tmp_int >> 0x18]; 35 } 36 for(i = 1; i <= 0xff; ++i){ 37 r1[i] += r1[i - 1]; 38 r2[i] += r2[i - 1]; 39 r3[i] += r3[i - 1]; 40 r4[i] += r4[i - 1]; 41 } 42 for(j = a + n; j != a; --j) 43 b[r1[(* (unsigned int *) j) & 0xff]--] = *j; 44 for(j = b + n; j != b; --j) 45 a[r2[((* (unsigned int *) j) >> 0x8) & 0xff]--] = *j; 46 for(j = a + n; j != a; --j) 47 b[r3[((* (unsigned int *) j) >> 0x10) & 0xff]--] = *j; 48 for(j = b + n; j != b; --j) 49 a[r4[(* (unsigned int *) j) >> 0x18]--] = *j; 50 } 51 52 template <typename T> 53 inline void Radix_Sort_64Bit(register const int n, T *a, T *b){ 54 unsigned r1[0x10000], r2[0x10000], r3[0x10000], r4[0x10000]; 55 memset(r1, 0, sizeof(r1)), memset(r2, 0, sizeof(r2)); 56 memset(r3, 0, sizeof(r3)), memset(r4, 0, sizeof(r4)); 57 58 register int i; 59 register unsigned long long tmp_int; 60 register T * j, *tar; 61 62 for(j = a + 1, tar = a + 1 + n; j != tar; ++j){ 63 tmp_int = * (unsigned long long *) j; 64 ++r1[tmp_int & 0xffff]; 65 ++r2[(tmp_int >> 0x10) & 0xffff]; 66 ++r3[(tmp_int >> 0x20) & 0xffff]; 67 ++r4[tmp_int >> 0x30]; 68 } 69 for(i = 1; i <= 0xffff; ++i){ 70 r1[i] += r1[i - 1]; 71 r2[i] += r2[i - 1]; 72 r3[i] += r3[i - 1]; 73 r4[i] += r4[i - 1]; 74 } 75 for(j = a + n; j != a; --j) 76 b[r1[(* (unsigned long long *) j) & 0xffff]--] = *j; 77 for(j = b + n; j != b; --j) 78 a[r2[((* (unsigned long long *) j) >> 0x10) & 0xffff]--] = *j; 79 for(j = a + n; j != a; --j) 80 b[r3[((* (unsigned long long *) j) >> 0x20) & 0xffff]--] = *j; 81 for(j = b + n; j != b; --j) 82 a[r4[(* (unsigned long long *) j) >> 0x30]--] = *j; 83 } 84 85 template <typename T> 86 inline void Radix_Sort_128Bit(register const int n, T *a, T *b){ 87 unsigned r1[0x10000], r2[0x10000], r3[0x10000], r4[0x10000]; 88 unsigned r5[0x10000], r6[0x10000], r7[0x10000], r8[0x10000]; 89 memset(r1, 0, sizeof(r1)), memset(r2, 0, sizeof(r2)); 90 memset(r3, 0, sizeof(r3)), memset(r4, 0, sizeof(r4)); 91 memset(r5, 0, sizeof(r5)), memset(r6, 0, sizeof(r6)); 92 memset(r7, 0, sizeof(r7)), memset(r8, 0, sizeof(r8)); 93 94 register int i; 95 register __uint128_t tmp_int; 96 register T * j, *tar; 97 98 for(j = a + 1, tar = a + 1 + n; j != tar; ++j){ 99 tmp_int = * (__uint128_t *) j; 100 ++r1[tmp_int & 0xffff]; 101 ++r2[(tmp_int >> 0x10) & 0xffff]; 102 ++r3[(tmp_int >> 0x20) & 0xffff]; 103 ++r4[(tmp_int >> 0x30) & 0xffff]; 104 ++r5[(tmp_int >> 0x40) & 0xffff]; 105 ++r6[(tmp_int >> 0x50) & 0xffff]; 106 ++r7[(tmp_int >> 0x60) & 0xffff]; 107 ++r8[tmp_int >> 0x70]; 108 } 109 for(i = 1; i <= 0xffff; ++i){ 110 r1[i] += r1[i - 1]; 111 r2[i] += r2[i - 1]; 112 r3[i] += r3[i - 1]; 113 r4[i] += r4[i - 1]; 114 r5[i] += r5[i - 1]; 115 r6[i] += r6[i - 1]; 116 r7[i] += r7[i - 1]; 117 r8[i] += r8[i - 1]; 118 } 119 for(j = a + n; j != a; --j) 120 b[r1[(* (__uint128_t *) j) & 0xffff]--] = *j; 121 for(j = b + n; j != b; --j) 122 a[r2[((* (__uint128_t *) j) >> 0x10) & 0xffff]--] = *j; 123 for(j = a + n; j != a; --j) 124 b[r3[((* (__uint128_t *) j) >> 0x20) & 0xffff]--] = *j; 125 for(j = b + n; j != b; --j) 126 a[r4[((* (__uint128_t *) j) >> 0x30) & 0xffff]--] = *j; 127 for(j = a + n; j != a; --j) 128 b[r5[((* (__uint128_t *) j) >> 0x40) & 0xffff]--] = *j; 129 for(j = b + n; j != b; --j) 130 a[r6[((* (__uint128_t *) j) >> 0x50) & 0xffff]--] = *j; 131 for(j = a + n; j != a; --j) 132 b[r7[((* (__uint128_t *) j) >> 0x60) & 0xffff]--] = *j; 133 for(j = b + n; j != b; --j) 134 a[r8[(* (__uint128_t *) j) >> 0x70]--] = *j; 135 } 136 137 template <typename T> 138 inline void Radix_Sort_80Bit(register const int n, T *a, T *b){ 139 unsigned r1[0x10000], r2[0x10000], r3[0x10000], r4[0x10000], r5[0x10000]; 140 memset(r1, 0, sizeof(r1)), memset(r2, 0, sizeof(r2)); 141 memset(r3, 0, sizeof(r3)), memset(r4, 0, sizeof(r4)); 142 memset(r5, 0, sizeof(r5)); 143 144 register int i; 145 register __uint128_t tmp_int; 146 register T * j, *tar; 147 148 for(j = a + 1, tar = a + 1 + n; j != tar; ++j){ 149 tmp_int = * (__uint128_t *) j; 150 ++r1[tmp_int & 0xffff]; 151 ++r2[(tmp_int >> 0x10) & 0xffff]; 152 ++r3[(tmp_int >> 0x20) & 0xffff]; 153 ++r4[(tmp_int >> 0x30) & 0xffff]; 154 ++r5[tmp_int >> 0x40]; 155 } 156 for(i = 1; i <= 0xffff; ++i){ 157 r1[i] += r1[i - 1]; 158 r2[i] += r2[i - 1]; 159 r3[i] += r3[i - 1]; 160 r4[i] += r4[i - 1]; 161 r5[i] += r5[i - 1]; 162 } 163 for(j = a + n; j != a; --j) 164 b[r1[(* (__uint128_t *) j)& 0xffff]--] = *j; 165 for(j = b + n; j != b; --j) 166 a[r2[(* (__uint128_t *) j) >> 0x10) & 0xffff]--] = *j; 167 for(j = a + n; j != a; --j) 168 b[r3[(* (__uint128_t *) j) >> 0x20) & 0xffff]--] = *j; 169 for(j = b + n; j != b; --j) 170 a[r4[(* (__uint128_t *) j) >> 0x30) & 0xffff]--] = *j; 171 for(j = a + n; j != a; --j) 172 b[r5[(* (__uint128_t *) j) >> 0x40) & 0xffff]--] = *j; 173 } 174 175 template <typename T> 176 inline void Radix_Sort_Bit(register const int n, T *a, T *b){ 177 size_t size_of_type = sizeof(a); 178 size_t num_of_buc = ((size_of_type >> 1) + 1) >> 1; 179 unsigned r[num_of_buc][0x10000]; 180 memset(r, 0, sizeof(r)); 181 register int i, k; 182 register unsigned short tmp_us; 183 register T * j, *tar; 184 for(k = 0; k < num_of_buc; ++k){ 185 for(j = a + 1, tar = a + 1 + n; j != tar; ++ j){ 186 tmp_us = * (((unsigned short *)j) + k); 187 ++ r[k][tmp_us]; 188 } 189 } 190 for(k = 0; k < num_of_buc; k++) 191 for(i = 1; i <= 0xffff; i++) 192 r[k][i] += r[k][i - 1]; 193 for(k = 0; k < num_of_buc; k += 0x2){ 194 i = k; 195 for(j = a + n; j != a; --j){ 196 tmp_us = * (((unsigned short *)j) + i); 197 b[r[i][tmp_us]--] = *j; 198 } 199 i |= 1; 200 for(j = b + n; j != b; --j){ 201 tmp_us = * (((unsigned short *)j) + i); 202 a[r[i][tmp_us]--] = *j; 203 } 204 } 205 } 206 inline void Radix_Sort_Float(register const int n, float *a, float *b){ 207 Radix_Sort_32Bit(n, a, b); 208 reverse(a + 1, a + 1 + n); 209 reverse(upper_bound(a + 1, a + 1 + n, float(-0.0)), a + 1 + n); 210 } 211 212 inline void Radix_Sort_Double(register const int n, double *a, double *b){ 213 Radix_Sort_64Bit(n, a, b); 214 reverse(a + 1, a + 1 + n); 215 reverse(upper_bound(a + 1, a + 1 + n, double(-0.0)), a + 1 + n); 216 } 217 218 inline void Radix_Sort_LDouble(register const int n, long double *a, long double *b){ 219 Radix_Sort_80Bit(n, a, b); 220 reverse(b + 1, b + 1 + n); 221 reverse(upper_bound(b + 1, b + 1 + n, (long double)(-0.0)), b + 1 + n); 222 swap(a, b); 223 } 224 225 inline void Radix_Sort_LDouble_B(register const int n, long double *a, long double *b){ 226 Radix_Sort_80Bit(n, a, b); 227 reverse(b + 1, b + 1 + n); 228 reverse(upper_bound(b + 1, b + 1 + n, (long double)(-0.0)), b + 1 + n); 229 } 230 231 double a[100], b[100]; 232 233 int main(){ 234 int n; 235 scanf("%d", &n); 236 for(int i = 1; i <= n; i++) 237 scanf("%lf", a + i); 238 Radix_Sort_Double(n, a, b); 239 for(int i = 1; i <= n; i++) 240 printf("%lf ", a[i]); 241 return 0; 242 }
Tools8:日志记录器
按照Python的日志级别设计的,可以按照C++的流式输出风格写,而且比较方便,但是由于现在DDL比较多,所以没来得及整理(自己用可以),先放代码:
(使用的时候一定要手动inited一次,然后再用dD iI wW eE cC,只有包含了logEnd之后才会把内容输出到文件或控制台中,否则都是暂存)
1 #include <ctime> 2 #include <fstream> 3 #include <functional> 4 #include <stringstream> 5 6 using namespace std; 7 8 struct Logger { 9 Logger(){}; 10 Logger(Logger &) = delete; 11 Logger & operator = (const Logger &) = delete; 12 std::ofstream lger; 13 char s[54]; 14 void init(); 15 std::string getTime(); 16 17 // true/false : 是否送入控制台 18 template <typename T> 19 inline void sendLog(const std::string &logLevel, const T& tar, const std::string& p, true_type); 20 template <typename T> 21 inline void sendLog(const std::string &logLevel, const T& tar, const std::string& p, false_type); 22 template <typename T> 23 inline void Critical(const T& tar, const std::string& p = ""); 24 template <typename T> 25 inline void Error(const T& tar, const std::string& p = ""); 26 template <typename T> 27 inline void Warning(const T& tar, const std::string& p = ""); 28 template <typename T> 29 inline void Info(const T& tar, const std::string& p = ""); 30 template <typename T> 31 inline void Debug(const T& tar, const std::string& p = ""); 32 void _Critical(const string &tar){ 33 Critical(tar); 34 } 35 void _Error(const string &tar){ 36 Error(tar); 37 } 38 void _Warning(const string &tar){ 39 Warning(tar); 40 } 41 void _Info(const string &tar){ 42 Info(tar); 43 } 44 void _Debug(const string &tar){ 45 Debug(tar); 46 } 47 48 ~Logger() { 49 lger.close(); 50 } 51 }; 52 53 namespace NoBody{ 54 Logger logger; 55 } 56 57 // _Logger 类通用,输出的时候带上一个logEnd可以向Logger输出一次,否则的话就不向Logger输出,产生积累效果 58 struct LogEnd {} logEnd; 59 60 struct _Logger{ 61 function<void(const string&)> target; 62 _Logger(function<void(const string&)> tar) : target(tar) {}; 63 stringstream ss; 64 int disabled; ///< 是否禁用(注意别忘了打开QWQ 65 inline void activate(bool force = false){ 66 if(force) disabled = 0; 67 else ++ disabled; 68 } 69 inline void deactivate(bool force = false){ 70 if(force) disabled = -1; 71 else -- disabled; 72 } 73 inline void call(){ 74 target(ss.str()); 75 } 76 inline void clear(){ 77 ss.str(""); 78 } 79 }; 80 81 // 用于禁用Logger的,在一个作用域中接收一个_Logger,然后进入作用域的时候禁用调试输出,离开的时候自动解除,自动对调用栈进行推导 82 struct DisableLogger{ 83 _Logger &tar; 84 DisableLogger(_Logger &_tar) : tar(_tar){ 85 tar.deactivate(false); 86 } 87 ~ DisableLogger(){ 88 tar.activate(false); 89 } 90 }; 91 92 template <typename T> 93 _Logger & operator << (_Logger &os, const T &tar) { 94 if(os.disabled) return os; 95 os.ss << tar; 96 #ifdef LOG_ADD_SPACE 97 os.ss << ' '; 98 #endif 99 return os; 100 } 101 template <> 102 _Logger & operator << (_Logger &os, const LogEnd &) { 103 if(os.disabled) return os; 104 os.call(); 105 os.clear(); 106 return os; 107 } 108 109 _Logger dD(bind(Logger::_Debug, &NoBody::logger, placeholders::_1)), 110 iI(bind(Logger::_Info, &NoBody::logger, placeholders::_1)), 111 wW(bind(Logger::_Warning, &NoBody::logger, placeholders::_1)), 112 eE(bind(Logger::_Error, &NoBody::logger, placeholders::_1)), 113 cC(bind(Logger::_Critical, &NoBody::logger, placeholders::_1)); 114 115 ostream &operator << (ostream &os, const VECTOR &vec) { 116 os << "(" << vec.x << "," << vec.y << ")"; 117 return os; 118 } 119 120 template <typename T1, typename T2> 121 ostream &operator << (ostream &os, const pair<T1, T2> &p) { 122 os << "(" << p.first << "," << p.second << ")"; 123 return os; 124 } 125 126 template <typename T1, typename T2, typename T3> 127 ostream &operator << (ostream &os, const tuple<T1, T2, T3> &t) { 128 os << '(' << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ')'; 129 return os; 130 } 131 132 template <typename T> 133 ostream &operator << (ostream &os, const vector<T> &c){ 134 // os << typeid(c).name() << ": ["; // 未来适配特定容器的时候改成这个 135 os << typeid(T).name() << ": ["; 136 for(const auto &it : c) 137 os << it << ','; 138 os << "]"; 139 return os; 140 } 141 142 void Logger::init(){ 143 string targetFile = "tmlx" + to_string(VERIFICATION::Singleton().GetArmyID()) + ".log"; 144 lger.open(targetFile); 145 iI << targetFile << (lger.is_open() ? " Opened." : "Not Opened!") << logEnd; 146 // lger.open("Logger" + getTime() + '\\' + to_string(VERIFICATION::Singleton().GetArmyID()) + ".log", ios_base::out); 147 } 148 149 std::string Logger::getTime() { 150 std::time_t curTime = std::time(NULL); 151 ctime_s(s, 54, &curTime); 152 (*strchr(s, '\n')) = '\0'; 153 return s; 154 } 155 156 template <typename T> 157 inline void Logger::sendLog(const std::string& logLevel, const T& tar, const std::string& p, true_type) { 158 UserAPI &API = UserAPI::Singleton(); 159 stringstream ss; 160 ss << logLevel << /*getTime() << " :" <<*/ 161 API.get_current_step() << ": "; 162 if(!p.empty()) ss << p << " : "; 163 ss << tar; 164 const string &tmp = ss.str(); 165 cerr << tmp << endl; 166 lger << tmp << endl; 167 } 168 169 template <typename T> 170 inline void Logger::sendLog(const std::string& logLevel, const T& tar, const std::string& p, false_type) { 171 UserAPI &API = UserAPI::Singleton(); 172 stringstream ss; 173 ss << logLevel << /*getTime() << " :" <<*/ 174 API.get_current_step() << ": "; 175 if(!p.empty()) ss << p << " : "; 176 ss << tar; 177 lger << ss.str() << endl; 178 } 179 template <typename T> 180 inline void Logger::Critical(const T& tar, const std::string& p) { 181 sendLog("[Critical]: ", tar, p, true_type()); 182 } 183 template <typename T> 184 inline void Logger::Error(const T& tar, const std::string& p) { 185 sendLog("[Error]: ", tar, p, true_type()); 186 } 187 template <typename T> 188 inline void Logger::Warning(const T& tar, const std::string& p) { 189 sendLog("[Warning]: ", tar, p, true_type()); 190 } 191 template <typename T> 192 inline void Logger::Info(const T& tar, const std::string& p) { 193 #ifdef _DEBUG 194 sendLog("[Info]: ", tar, p, true_type()); 195 #else 196 sendLog("[Info]: ", tar, p, false_type()); 197 #endif 198 } 199 template <typename T> 200 inline void Logger::Debug(const T& tar, const std::string& p) { 201 #ifdef _DEBUG 202 sendLog("[Debug]: ", tar, p, true_type()); 203 #else 204 sendLog("[Debug]: ", tar, p, false_type()); 205 #endif 206 }