一些日常工具集合(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
C++ 11

  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的参数)。

  1.    int __builtin_ffs (int x) :查询x二进制最后一个1是第几位
  2.    int __builtin_clz (unsigned int x) :查询x有多少个前导0,If x is 0, the result is undefined.
  3.    int __builtin_ctz (unsigned int x) :查询x有多少个后缀0,If x is 0, the result is undefined.
  4.    int __builtin_popcount (unsigned int x) :查询x有多少个1,在洛谷日爆未来的某期内我还了解到了还可以加#pragma GCC target ("popcnt")直接把这玩意转化成指令加速,优化效果高达70%(网上某些题的实验)
  5.    int __builtin_parity (unsigned int x) :查询x的二进制奇偶校验,也就是x中1的个数模2
  6.    uint16_t __builtin_bswap16 (uint16_t x) :按照字节翻转二进制位,例如0xaabb翻转成为0xbbaa,然后16可替换为32,64,表示位数
  7.    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=6205849https://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上是有效的,例如提交记录

没有优化

register优化

O2优化

O2+register

可能存在干扰因素,有兴趣的可以自己去各大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 }

 

posted @ 2018-07-18 00:32  Creeper_LKF  阅读(954)  评论(0编辑  收藏  举报