【C++】快读&快写模板及火车头优化代码

快读快写简介

快读快写,顾名思义,就是提升输入和输出的速度。在这里简单介绍一下几种输入输出的优劣。

  • C++ cin / cout 输入输出:优点是读入的时候不用管数据类型,但是缺点就是比scanf/printf慢一些。

这里给一个关同步流的代码,可以显著优化 cin / cout 的速度:

ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);

需要注意的是,关了同步流之后就不能再用 scanf / printf 了。

  • C scanf / printf 输入输出:与 C++ 对比,比 cin / cout 快一些,但使用方法细节比较多,容易出锅。

  • 快读/快写:只能处理整数读入 / 输出,但是要比标准输入输出函数都快得多。

    • 一般来讲,快读快写在针对数据量不是很大的输入输出的时候显得比较无力,但如果是多组数据或者输入量较多,就可以显著提升效率。

    • 开不开inline差不多。

    • 还有一种更快的fread()函数型快读,比一般的快读都要快,这里主要给这种。

快读快写代码

char *p1, *p2, buf[N];
#define nc() (p1 == p2 && (p2 = (p1 = buf) +\
fread(buf, 1, N, stdin), p1 == p2) ? EOF : *p1 ++ )
LL read()
{
    LL x = 0, f = 1;
    char ch = nc();
    while (ch < 48 || ch > 57)
    {
        if (ch == '-') f = -1;
        ch = nc();
    }
    while (ch >= 48 && ch <= 57)
        x = (x << 3) + (x << 1) + (ch ^ 48), ch = nc();
    return x * f;
}

char obuf[N], *p3 = obuf;
#define putchar(x) (p3 - obuf < N) ? (*p3 ++ = x) :\
(fwrite(obuf, p3 - obuf, 1, stdout), p3 = obuf, *p3 ++ = x)
inline void write(LL x)
{
    if (!x)
    {
        putchar('0');
        return;
    }
    LL len = 0, k1 = x, c[40];
    if (k1 < 0) k1 = -k1, putchar('-');
    while (k1) c[len ++ ] = k1 % 10 ^ 48, k1 /= 10;
    while (len -- ) putchar(c[len]);
}

这里说一下代码里几个卡常方式:

  1. 字符判断用 ASCII 值代替字符
  2. 字符和数字之间的转换由 +'0',-'0' 变为 ^48
  3. x * 10 改为位运算
  4. 快写不用递归的方式
  5. 读入、输出时用 fwrite

注:在用了快读快写之后,我们需要清空缓冲区,应该在程序最后加一句话:

fwrite(obuf, p3 - obuf, 1, stdout);

火车头优化

#pragma GCC target("avx")
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")

最后,如果觉得对您有帮助的话,点个赞再走吧!