适用于C++11以上的快速IO

压行版代码 19行

注意事项

仅适用于C++11及以上,否则如果你得到CE后果自负。

代码

原版

加在using namespace std;下一行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//#define FIO //开启加速模式 将不能使用键盘读入
struct IO {
#ifdef FIO
const static int BUFSIZE = 1 << 20;
char buf[BUFSIZE], obuf[BUFSIZE], *p1, *p2, *pp;
inline char gc() {
return (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, BUFSIZE, stdin), p1 == p2) ? EOF : *p1++);
}
inline void pc(char x) {
((pp - obuf == BUFSIZE && (fwrite(obuf, 1, BUFSIZE, stdout), pp = obuf)), *pp = x, pp++);
}
inline void flush() {
fwrite(obuf, 1, pp - obuf, stdout);
}
IO() {
p1 = buf, p2 = buf, pp = obuf;
}
~IO() {
fwrite(obuf, 1, pp - obuf, stdout);
}
#else
int (*gc)() = &getchar;
int (*pc)(int) = &putchar;
inline void flush() {};
#endif
template<typename Tp = int>
inline Tp read() {
Tp s = 0;
int f = 1;
char ch = gc();
while (!isdigit(ch)) f = (ch == '-' ? -1 : 1), ch = gc();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = gc();
return s * f;
}
template<typename Tp>
void read(Tp &x) {
x = read();
}
template<typename Tp, typename... Ts>
void read(Tp &x, Ts &...val) {
x = read<Tp>();
read(val...);
}
template<typename Tp>
void write(Tp x) {
if (x < 0) pc('-'), x = -x;
static char sta[20];
int top = 0;
do sta[top++] = x % 10 + '0', x /= 10;
while (x);
while (top)
pc(sta[--top]);
}
template<typename Tp, typename... Ts>
void write(Tp x, Ts... val) {
write(x);
pc(' ');
write(val...);
}
template<typename... Ts>
void writeln(Ts... val) {
write(val...);
pc('\n');
}
} io;

压行版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//#define FIO //开启加速模式 将不能使用键盘读入
struct IO{
#ifdef FIO
const static int BUFSIZE=1<<20;char buf[BUFSIZE],obuf[BUFSIZE],*p1,*p2,*pp;inli\
ne char gc(){return(p1==p2&&(p2=(p1=buf)+fread(buf,1,BUFSIZE,stdin),p1==p2)?EOF\
:*p1++);}inline void pc(char x){((pp-obuf==BUFSIZE&&(fwrite(obuf,1,BUFSIZE,stdo\
ut),pp=obuf)),*pp=x,pp++);}inline void flush(){fwrite(obuf,1,pp-obuf,stdout);}I\
O(){p1=buf,p2=buf,pp=obuf;}~IO(){fwrite(obuf,1,pp-obuf,stdout);}
#else
int(*gc)()=&getchar;int(*pc)(int)=&putchar;inline void flush(){};
#endif
template<typename Tp=int>inline Tp read(){Tp s=0;int f=1;char ch=gc();while(!is\
digit(ch))f=(ch=='-'?-1:1),ch=gc();while(isdigit(ch))s=s*10+(ch^48),ch=gc();ret\
urn s*f;}template<typename Tp>void read(Tp&x){x=read();}template<typename Tp,ty\
pename...Ts>void read(Tp&x,Ts&...val){x=read<Tp>();read(val...);}template<typen\
ame Tp>void write(Tp x){if(x<0)pc('-'),x=-x;static char sta[20];int top=0;do st\
a[top++]=x%10+'0',x/=10;while(x);while(top)pc(sta[--top]);}template<typename Tp\
,typename...Ts>void write(Tp x,Ts...val){write(x);pc(' ');write(val...);}templa\
te<typename...Ts>void writeln(Ts...val){write(val...);pc('\n');}}io;

速度

这个模板是非常快的:

LOJ #7 / 读入3e6个long long / 五组数据开启-Ofast优化不开启优化
调试模式getchar433ms796ms
加速模式fread 无法使用键盘输入250ms539ms

用法

本模板实现了任何整数类型的读入/输出,同时可以自己写输出函数并使用高速IO。

读入

返回值模式

int x = io.read(); 读入一个int类型整数 xx

long long x = io.read<long long>(); 读入一个long long类型整数 xx (其他数据类型如__int128_tunsigned以此类推 不指定模板参数默认为int)

引用模式

1
2
3
4
5
6
7
8
int x;
io.read(x);//读入一个int类型整数x

__int128_t a;
int b;
unsigned long long c;
short d;
io.read(a,b,c,d);//如果使用传参方式可以自动推断类型并可以一次读入任意多个整数

输出

1
2
3
4
5
6
int x=1926,y=8,z=17;
long long a=1145141919810;
io.write(x,y,z);//与带参数的io.read()类似,如果一次输出多个数会自动加上空格,同样可以自动推断类型

io.writeln(x,y);//相当于使用io.write()后手动输出一个换行符

自定义读入/输出

模板定义了pc,gc两个宏(因为他们是宏所以不需要加io.前缀),用它们代替putchargetchar,开启快速模式后putchargetchar会失效。

自定义读入/读出函数必须要放在IO结构体内。

最新版本已经统一了API,只需要简单地用io.pcio.gc分别代替putchargetchar即可。自定义IO函数可以写在任何地方。

下面这个示例函数可以输出一个string

1
2
3
4
5
6
7
8
struct IO{
...//省略60行
} io;

void writeString(string str){
for(char ch:str) io.pc(ch);
}
writeString("I AK IOI");

手动刷新输出缓冲区

如果你不知道这是什么意思可以跳过这段内容。

一般情况下,模板会在你的程序退出时自动刷新输出缓冲区并输出其中的全部内容。

如果你想在程序运行中手动刷新缓冲区(比如IO交互题)可以使用io.flush()

该函数在调试模式下是一个空函数(因为getcharputchar都是即时操作的)。


适用于C++11以上的快速IO
https://www.d0j1a1701.cc/p/d420019/
作者
d0j1a_1701
发布于
2021年10月10日
许可协议
CC-BY-SA