前言
寫的很亂,各種內容都有。僅僅是為了記錄一下
而且內容極其不嚴謹(沒錯,只有實踐,沒有理論)!請各位謹慎駕駛!
強制內聯
#define Inline __inline__ __attribute__((always_inline))
本地測試結果:
-
開O2之后inline和Inline加不加沒啥用
-
不開O2時inline可能會有負優化,而Inline會讓程序快很多
當然也可以強制不inline
直接在函數名前加
__attribute__((noinline))
利用位運算實現大小寫轉化
可以這么寫
char ToUpper(char a) {return (a >= 'a' && a <= 'z') ? a ^ ' ' : a;}
實測比c++內置的toupper
快6倍。。
enum類型
這玩意兒叫“枚舉”
格式如下:
enum [enumeration name] {enumerator1[=value1], enumerator2[=value2], ...};
其中,第二個變量的取值默認是第一個變量取值+1,第一個默認是0,當然也可以自己設定
一個簡單的栗子
enum NOIP {a, b, c, d = 22};
cout << c << " " << d;
將會輸出2 22
自定義輸入輸出流
這部分有點硬核啊。。
一個簡單的栗子是這樣的
#include<bits/stdc++.h>
using namespace std;
class Pair {
private:
int id;
string s;
public:
friend ostream& operator << (ostream& os, Pair& a) {
os << a.s << ":" << a.id << "\n";
return os;
}
friend istream& operator >> (istream& is, Pair& a) {
is >> a.s >> a.id;
return is;
}
};
int main( ) {
Pair a;
cin >> a;
cout << a;
return 0;
}
//input: abc 123
//output : abc:123
注意這里我們實際上還是在用cin / cout輸入輸出
輸入輸出流在OI中常常應用於輸入輸出優化。
struct InputOutputStream {
enum { SIZE = 1000001 };
char ibuf[SIZE], *s, *t, obuf[SIZE], *oh;
InputOutputStream() : s(), t(), oh(obuf) {}
~InputOutputStream() { fwrite(obuf, 1, oh - obuf, stdout); }
inline char read() {
if (s == t) t = (s = ibuf) + fread(ibuf, 1, SIZE, stdin);
return s == t ? -1 : *s++;
}
template <typename T>
inline InputOutputStream &operator>>(T &x) {
static char c;
static bool iosig;
for (c = read(), iosig = false; !isdigit(c); c = read()) {
if (c == -1) return *this;
iosig |= c == '-';
}
for (x = 0; isdigit(c); c = read()) x = x * 10 + (c ^ '0');
if (iosig) x = -x;
return *this;
}
inline void print(char c) {
if (oh == obuf + SIZE) {
fwrite(obuf, 1, SIZE, stdout);
oh = obuf;
}
*oh++ = c;
}
template <typename T>
inline void print(T x) {
static int buf[23], cnt;
if (x != 0) {
if (x < 0) print('-'), x = -x;
for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 | 48;
while (cnt) print((char)buf[cnt--]);
} else print('0');
}
template <typename T>
inline InputOutputStream &operator<<(const T &x) {
print(x);
return *this;
}
} io;
template
template,中文名:模板
分為兩類,一種叫類模板
,一種叫函數模板
類模板我用的不多
函數模板用的多一些
下面是一個求最大值的模板,c++的標准庫中也是這么實現的,因此同時存在的話會引起CE
template <typename T>
inline T const& max(T const &a, T const &b) {
return a > b ? a : b;
}
如果直接調用的話,當\(a, b\)的類型不同時會引起CE。
這時可以直接強制類型轉化
int a = 1e9;
long long b = 1e18;
long long c = max<int>(a, b);
//the output is 1e9
int a = 1e9;
long long b = 1e18;
long long c = max<long long>(a, b);
//the output is 1e18
預編譯黑科技
第一條是強制開棧空間
后面的並不清楚在干啥,貌似可以強制\(O_2\)
#pragma comment(linker, "/STACK:102400000,102400000")
#pragma GCC diagnostic error "-std=c++11"
#pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3)
#pragma GCC target("avx","sse2")
__builtin系列
- __builtin_popcount(unsigned int n)
計算\(n\)的二進制表示中有多少個1
- __builtin_parity(unsigned int n)
判斷\(n\)的二進制表示中1的個數奇偶性(要你何用?)
- __builtin_ffs(unsigned int n)
判斷\(n\)的二進制末尾最后一個1的位置,從1開始
- __builtin_ctz(unsigned int n)
判斷\(n\)的二進制末尾\(0\)的個數
- __builtin_clz(unsigned int n)
判斷\(n\)的二進制前導0的個數
指針的騷操作
通過指針實現負下標數組
#include<bits/stdc++.h>
using namespace std;
int main() {
int __a[21];
for(int i = 0; i <= 20; i++) __a[i] = i;
int *const a = &__a[10];
printf("%d %d %d", a[7], a[0], a[-7]);
}