在寫代碼的時候,咱們經常會用一些小技巧,下面作簡單介紹node
如題,開優化開關。ios
有的OJ上有O2優化選項,固然,你也能夠這樣:在代碼開頭這樣加一句:ide
#pragma GCC optimize("O1") #pragma GCC optimize("O2") #pragma GCC optimize("O3")
(逃~函數
Tips:此方法對STL很是有效!(NOIP賽場上我不知道能不能用,建議不要用)優化
inline
關鍵字(常數優化)能夠在一個函數的最開始加上inline,如:spa
inline int max(int a, int b) { if (a < b) return b; return a; }
意義:在編譯時,把這個函數放到使用它的地方,如:3d
inline int max(int a, int b) _ { \ if (a < b) | return b; }----------. return a; | | } _/ | | int main() | 編譯時 { | 直接包 int a, b, c; | 含進去, cin >> a >> b >> c; | 加快程 cout << max(a, b) << endl; <----------| 序運行 | 速度。 cout << max(a, c) << endl; <----------| | cout << max(b, c) << endl; <----------/ return 0; }
使用貼士:code
inline
,這樣可能會更慢!inline
, 這樣並不會優化!register
關鍵字(常數優化)能夠在一個變量聲明的類型前面加上這個關鍵字。例:blog
// example #1: register int a; // example #2: register long long b[10007]; // example #3: struct node1 { int rank; int num; }; register node1 c; // example #4: register struct node2 { int a, b; int c; } d;
原理:咱們運行的程序會放在內存裏,因此訪問速度仍是較慢,因此咱們能夠將經常使用的變量放在離CPU更近的寄存器裏(即register)。遞歸
使用小貼士:
register
的變量只能在函數裏聲明!!!(這也很好理解)example #4
,register能夠寫在struct
開頭。register
。(e.g.循環變量i, j, k
)能夠給一個函數聲明成template + typename的形式。如:
// example: template <typename _Tp> _Tp max(_Tp a, _Tp b) { if (a > b) return a; return b; } // use: int x, y; cin >> x >> y; cout << max(x, y) << endl; cout << max<int>(x, y) << endl; //這兩行等價
能夠看到,聲明這種函數的方法是在開頭加上
template <typename type1, typename type2, ...> // 類型個數任意
注意:若一個typename(即類型)不是該函數的一個輸入參數,則需用<...>
的形式告訴函數這個typename的類型!
先給代碼嚶嚶嚶
char BufferRead[1 << 15]; int rLen = 0, rPos = 0; inline int Getchar(){ if (rPos == rLen) rPos = 0, rLen = fread(BufferRead, 1, 1 << 15, stdin); if (rPos == rLen) return EOF; return BufferRead[rPos++]; }
說明:
1 << 15
個字節,而從文件讀入時會讀到文件結束符從而中止讀入,不會出問題)fread
能夠經過這篇文章簡要了解一下fast_IO #1
)代碼仍是很簡單的,以下:
template <typename _TpInt> inline _TpInt read() { register int flag = 1; register char c = Getchar(); while ((c > '9' || c < '0') && c != '-') c = Getchar(); if (c == '-') flag = -1, c = Getchar(); register _TpInt init = (c & 15); while ((c = Getchar()) <= '9' && c >= '0') init = (init << 3) + (init << 1) + (c & 15); return init * flag; }
幾點說明:
flag
是負數標記(c & 15)
:'0'
的ASCII
碼是48,(c & 15)
此處等於(c % 16)
,因此本句(c & 15)
的意義是c-'0'
(init << 3) + (init << 1) = (init * 8) + (init * 2) = (init * 10)
typename
:能夠讀不一樣的類型Tips:'&'
和'<<'
是位運算,關於位運算,能夠上百度查資料
應用例子:
int a; long long b; short c; a = read<int>(); b = read<long long>(); c = read<short>();
fast_IO #2
)仿照整數快讀,寫出實數快讀:
template <typename _TpRealnumber> inline double readr() { register int flag = 1; register char c = Getchar(); while ((c > '9' || c < '0') && c != '-') c = Getchar(); if (c == '-') flag = -1, c = Getchar(); register _TpRealnumber init = (c & 15); while ((c = Getchar()) <= '9' && c >= '0') init = init * 10 + (c & 15); if (c != '.') return init * flag; register _TpRealnumber l = 0.1; while ((c = Getchar()) <= '9' && c >= '0') init = init + (c & 15) * l, l *= 0.1; return init * flag; }
沒什麼好說明的。
應用例子:
float d; double e; d = readr<float>(); e = readr<double>();
fast_IO #3
)使用遞歸執行。
template <typename _TpInt> inline void write(_TpInt x) { if (x < 0) { putchar('-'); write<_TpInt>(~x + 1); } else { if (x > 9) write<_TpInt>(x / 10); putchar(x % 10 + '0'); } }
說明:
(~x+1) = -x
,此處是爲了unsigned
型整數而寫此句if (x > 9)
,則會死循環write<int>(-2147483648);
write<short>(-65536);
etc...
應用例子:
write<int>(1); printf("\n"); write<short>(-891); printf("\n"); write<int>(-2147483647); printf("\n"); long long n = 6; write<long long>(n); printf("\n");
1 // luogu-judger-enable-o2 2 /* 3 Problem: C++ 代碼模板 4 Author: 航空信奧 5 Date: 2018/08/02 6 */ 7 #pragma GCC optimize("O1") 8 #pragma GCC optimize("O2") 9 #pragma GCC optimize("O3") 10 #include <stdio.h> 11 #include <iostream> 12 #include <string.h> 13 #include <vector> 14 #include <map> 15 #include <set> 16 #define lowbit(a) ((a) & (~a + 1)) // define 快 17 using namespace std; 18 namespace AuthorName { // 防重名 19 inline char Getchar(); 20 template <typename _TpInt> inline _TpInt read(); 21 template <typename _TpRealnumber> inline double readr(); 22 template <typename _TpInt> inline void write(_TpInt x); 23 template <typename _TpSwap> inline void swap(_TpSwap &x, _TpSwap &y); 24 25 int main() 26 { 27 // here : DO SOMETHING 28 return 0; 29 } 30 31 char BufferRead[1 << 15]; 32 int rLen = 0, rPos = 0; 33 inline char Getchar() 34 { 35 if (rPos == rLen) rPos = 0, rLen = fread(BufferRead, 1, 1 << 15, stdin); 36 if (rPos == rLen) return EOF; 37 return BufferRead[rPos++]; 38 } 39 40 template <typename _TpInt> 41 inline _TpInt read() 42 { 43 register int flag = 1; 44 register char c = Getchar(); 45 while ((c > '9' || c < '0') && c != '-') 46 c = Getchar(); 47 if (c == '-') flag = -1, c = Getchar(); 48 register _TpInt init = (c & 15); 49 while ((c = Getchar()) <= '9' && c >= '0') 50 init = (init << 3) + (init << 1) + (c & 15); 51 return init * flag; 52 } 53 54 template <typename _TpRealnumber> 55 inline double readr() 56 { 57 register int flag = 1; 58 register char c = Getchar(); 59 while ((c > '9' || c < '0') && c != '-') 60 c = Getchar(); 61 if (c == '-') flag = -1, c = Getchar(); 62 register _TpRealnumber init = (c & 15); 63 while ((c = Getchar()) <= '9' && c >= '0') 64 init = init * 10 + (c & 15); 65 if (c != '.') return init * flag; 66 register _TpRealnumber l = 0.1; 67 while ((c = Getchar()) <= '9' && c >= '0') 68 init = init + (c & 15) * l, l *= 0.1; 69 return init * flag; 70 } 71 72 template <typename _TpInt> 73 inline void write(_TpInt x) 74 { 75 if (x < 0) { 76 putchar('-'); 77 write<_TpInt>(~x + 1); 78 } 79 else { 80 if (x > 9) write<_TpInt>(x / 10); 81 putchar(x % 10 + '0'); 82 } 83 } 84 85 template <typename _TpSwap> 86 inline void swap(_TpSwap &x, _TpSwap &y) 87 { 88 _TpSwap t = x; 89 x = y; 90 y = t; 91 } 92 } 93 94 int main() 95 { 96 AuthorName::main(); 97 return 0; 98 }