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

压行版代码

注意事项

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

长达163行的快读!(振声

代码

原版

加在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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* d0j1a_1701 FastIO full ver. 3.5 */
//#define FIO //开启加速模式 将不能使用键盘读入
struct IO {
#ifdef FIO
const static int BUFSIZE = 1 << 20;
char buf[BUFSIZE], obuf[BUFSIZE], *p1, *p2, *pp;
inline char getchar() {
return (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, BUFSIZE, stdin), p1 == p2) ? EOF : *p1++);
}
inline void putchar(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() {
fwrite("Warning: Macro 'FIO' has been defined, keyboard input will be ignored.\n", 1, 71, stderr);
p1 = buf, p2 = buf, pp = obuf;
}
~IO() {
fwrite(obuf, 1, pp - obuf, stdout);
}
#else
int (*getchar)() = &::getchar;
int (*putchar)(int) = &::putchar;
inline void flush() {};
#endif
string sep = " ";
int k = 2;
template<typename Tp, typename enable_if<is_integral<Tp>::value>::type * = nullptr>
inline int read(Tp &s) {
int f = 1;
char ch = getchar();
s = 0;
while (!isdigit(ch) && ch != EOF) f = (ch == '-' ? -1 : 1), ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
s *= f;
return ch != EOF;
}
template<typename Tp, typename enable_if<is_floating_point<Tp>::value>::type * = nullptr>
inline int read(Tp &s) {
int f = 1;
char ch = getchar();
s = 0;
while (!isdigit(ch) && ch != EOF && ch != '.') f = (ch == '-' ? -1 : 1), ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
if(ch == EOF) return false;
if(ch == '.') {
Tp eps = 0.1;
ch = getchar();
while (isdigit(ch)) s = s + (ch ^ 48) * eps, ch = getchar(), eps /= 10;
}
s *= f;
return ch != EOF;
}
inline int read(char &c) {
char ch = getchar();
while(isspace(ch) && ch != EOF) ch = getchar();
if(ch != EOF) c = ch;
return ch != EOF;
}
inline int read(char *c) {
char ch = getchar();
while(isspace(ch) && ch != EOF) ch = getchar();
while(!isspace(ch) && ch != EOF) *(c++) = ch, ch = getchar();
return ch != EOF;
}
inline int read(string &s) {
s.clear();
char ch = getchar();
while(isspace(ch) && ch != EOF) ch = getchar();
while(!isspace(ch) && ch != EOF) s += ch, ch = getchar();
return ch != EOF;
}
inline int getline(char *c, const char &ed = '\n') {
char ch = getchar();
while(ch != ed && ch != EOF) *(c++) = ch, ch = getchar();
return ch != EOF;
}
inline int getline(string &s, const char &ed = '\n') {
s.clear();
char ch = getchar();
while(ch != ed && ch != EOF) s += ch, ch = getchar();
return ch != EOF;
}
template<typename Tp = int>
inline Tp read() {
Tp x;
read(x);
return x;
}
template<typename Tp, typename... Ts>
int read(Tp &x, Ts &...val) {
return read(x) && read(val...);
}
template<typename Tp, typename enable_if<is_integral<Tp>::value>::type * = nullptr>
IO & write(Tp x) {
if (x < 0) putchar('-'), x = -x;
static char sta[20];
int top = 0;
do sta[top++] = x % 10 + '0', x /= 10;
while (x);
while (top)
putchar(sta[--top]);
return *this;
}
inline IO &write(const string &str) {
for(char ch : str) putchar(ch);
return *this;
}
inline IO &write(const char *str) {
while(*str != '\0') putchar(*(str++));
return *this;
}
inline IO &write(char *str) {
return write((const char *)str);
}
inline IO &write(const char &ch) {
return putchar(ch), *this;
}
template<typename Tp, typename enable_if<is_floating_point<Tp>::value>::type * = nullptr>inline IO & write(Tp x) {
const static long long pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 100000000000000000, 100000000000000000};
const auto &n = pow10[k];
if(x == 0) {
putchar('0'), putchar('.');
for(int i = 1; i <= k; ++i) putchar('0');
return *this;
}
if(x < 0) putchar('-'), x = -x;
long long d = (long long)(x + 1e-12), y = (long long)(x * n + 0.5);
write(d), putchar('.');
static char sta[20];
int top = 0;
for(; top < k; y /= 10) sta[top++] = y % 10 ^ 48;
while(top) putchar(sta[--top]);
return*this;
}
template<typename Tp, typename... Ts>
inline IO &write(Tp x, Ts... val) {
write(x);
write(sep);
write(val...);
return *this;
}
template<typename... Ts>
inline IO &writeln(Ts... val) {
write(val...);
putchar('\n');
return *this;
}
inline IO &writeln(void) {
putchar('\n');
return *this;
}
template<typename Tp>
inline IO &writeWith(Tp x, const string &s) {
write(x), write(s);
return *this;
}
inline IO &setsep(const string &s) {
return sep = s, *this;
}
inline IO &setprecision(const int &K) {
return k = K, *this;
}
} io;

压行版

1
2
3
4
5
6
7
8
9
/* d0j1a_1701 FastIO full ver. 3.5 */
//#define FIO //开启加速模式 将不能使用键盘读入
struct IO{
#ifdef FIO
const static int BUFSIZE=1<<20;char buf[BUFSIZE],obuf[BUFSIZE],*p1,*p2,*pp;inline char getchar(){return(p1==p2&&(p2=(p1=buf)+fread(buf,1,BUFSIZE,stdin),p1==p2)?EOF:*p1++);}inline void putchar(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(){fwrite("Warning: Macro 'FIO' has been defined, keyboard input will be ignored.\n",1,71,stderr);p1=buf,p2=buf,pp=obuf;}~IO(){fwrite(obuf,1,pp-obuf,stdout);}
#else
int(*getchar)()=&::getchar;int(*putchar)(int)=&::putchar;inline void flush(){};
#endif
string sep=" ";int k=2;template<typename Tp,typename enable_if<is_integral<Tp>::value>::type* =nullptr>inline int read(Tp&s){int f=1;char ch=getchar();s=0;while(!isdigit(ch)&&ch!=EOF)f=(ch=='-'?-1:1),ch=getchar();while(isdigit(ch))s=s*10+(ch^48),ch=getchar();s*=f;return ch!=EOF;}template<typename Tp,typename enable_if<is_floating_point<Tp>::value>::type* =nullptr>inline int read(Tp&s){int f=1;char ch=getchar();s=0;while(!isdigit(ch)&&ch!=EOF&&ch!='.')f=(ch=='-'?-1:1),ch=getchar();while(isdigit(ch))s=s*10+(ch^48),ch=getchar();if(ch==EOF)return false;if(ch=='.'){Tp eps=0.1;ch=getchar();while(isdigit(ch))s=s+(ch^48)*eps,ch=getchar(),eps/=10;}s*=f;return ch!=EOF;}inline int read(char&c){char ch=getchar();while(isspace(ch)&&ch!=EOF)ch=getchar();if(ch!=EOF)c=ch;return ch!=EOF;}inline int read(char*c){char ch=getchar();while(isspace(ch)&&ch!=EOF)ch=getchar();while(!isspace(ch)&&ch!=EOF)*(c++)=ch,ch=getchar();return ch!=EOF;}inline int read(string&s){s.clear();char ch=getchar();while(isspace(ch)&&ch!=EOF)ch=getchar();while(!isspace(ch)&&ch!=EOF)s+=ch,ch=getchar();return ch!=EOF;}inline int getline(char*c,const char&ed='\n'){char ch=getchar();while(ch!=ed&&ch!=EOF)*(c++)=ch,ch=getchar();return ch!=EOF;}inline int getline(string&s,const char&ed='\n'){s.clear();char ch=getchar();while(ch!=ed&&ch!=EOF)s+=ch,ch=getchar();return ch!=EOF;}template<typename Tp=int>inline Tp read(){Tp x;read(x);return x;}template<typename Tp,typename...Ts>int read(Tp&x,Ts&...val){return read(x)&&read(val...);}template<typename Tp,typename enable_if<is_integral<Tp>::value>::type* =nullptr>IO&write(Tp x){if(x<0)putchar('-'),x=-x;static char sta[20];int top=0;do sta[top++]=x%10+'0',x/=10;while(x);while(top)putchar(sta[--top]);return*this;}inline IO&write(const string&str){for(char ch:str)putchar(ch);return*this;}inline IO&write(const char*str){while(*str!='\0')putchar(*(str++));return*this;}inline IO&write(char*str){return write((const char*)str);}inline IO&write(const char&ch){return putchar(ch),*this;}template<typename Tp,typename enable_if<is_floating_point<Tp>::value>::type* =nullptr>inline IO&write(Tp x){const static long long pow10[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000,1000000000000,10000000000000,100000000000000,1000000000000000,10000000000000000,100000000000000000,100000000000000000,100000000000000000};const auto&n=pow10[k];if(x==0){putchar('0'),putchar('.');for(int i=1;i<=k;++i)putchar('0');return*this;}if(x<0)putchar('-'),x=-x;long long d=(long long)(x+1e-12),y=(long long)(x*n+0.5);write(d),putchar('.');static char sta[20];int top=0;for(;top<k;y/=10)sta[top++]=y%10^48;while(top)putchar(sta[--top]);return*this;}template<typename Tp,typename...Ts>inline IO&write(Tp x,Ts...val){write(x);write(sep);write(val...);return*this;}template<typename...Ts>inline IO&writeln(Ts...val){write(val...);putchar('\n');return*this;}inline IO&writeln(void){putchar('\n');return*this;}template<typename Tp>inline IO&writeWith(Tp x,const string&s){write(x),write(s);return*this;}inline IO&setsep(const string&s){return sep=s,*this;}inline IO&setprecision(const int&K){return k=K,*this;}}io;

速度

这个模板是非常快的:

LOJ #7 / 读入 3×1063\times 10^6long long / 五组数据开启-O2优化不开启优化
调试模式getchar288ms479ms
加速模式fread 无法使用键盘输入189ms429ms

用法

本模板实现了任何整数类型/任何浮点类型/C风格字符串/std::string的读入/输出,同时可以自己写输出函数并使用高速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
9
int x;
io.read(x);//读入一个int类型整数x

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

引用模式的返回值可以判断是否读到了EOF,用法类似于cin

1
2
3
int a,b;
while(io.read(a,b)) io.writeln(a+b);
//和while(cin >> a >> b) cout << a+b << endl;//等价

输出

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

io.writeln(x,a);//相当于使用io.write()后手动输出一个换行符
//输出: 1926 1145141919810[换行]

io.writeln();//可不加参数
//输出: [换行]

高级功能

使用io.setsep可控制分隔符

1
2
io.setsep(",").writeln(1,2,3,4,5);
//输出: 1,2,3,4,5[换行]

使用io.setprecision可控制浮点数输出精度(四舍五入)

1
2
io.setprecision(3).writeln(3.1415926);
//输出: 3.142[换行]

io.writeWith(x,y) = io.write(x).write(y)

1
2
for(int x:{1,2,3,4,5}) io.writeWith(x,' ');
//输出: 1 2 3 4 5

自定义读入/输出

只需要简单地用io.putchario.getchar分别代替putchargetchar即可。自定义IO函数可以写在任何地方。

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

1
2
3
4
5
6
7
8
struct IO{
...
} io;

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

手动刷新输出缓冲区

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

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

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

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

如果你要将高速IO与其他输出函数(如printf)混用,则需要在使用其他输出函数之前先调用io.flush()


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