当某天,本蒟蒻沉迷于卡常的时候:

我……

突然,YYKdalao说:用文操快读啊!

然后

喔~目瞪口呆

不多说,上源码:

本来用的读入方式:

inline void Read( int &x ) {
x = 0; char ch = getchar();
for( ; ch < '0' || ch > '9'; ch = getchar() );
for( ; ch >= '0' && ch <= '9'; ch = getchar() )
x = x * 10 + ch - '0';
return;
}

文操快读:

const int MAX_SIZE = 1 << 15;
char *l, *r, buf[ MAX_SIZE ];
inline int gc() {
if( l == r )
if( l == ( r = ( l = buf ) + fread( buf, 1, MAX_SIZE, stdin ) ) ) return -1;
return *l++;
}
inline void Read( int &x ) {
char c = gc();
for(; c < 48 || c > 57; c = gc() );
for( x = 0; c > 47 && c < 58; c = gc() )
x = ( x << 3 ) + ( x << 1 ) + ( c ^ 48 );
return;
}

以下为2019.11.04 update

实际上,输出也同样可以使用 fwrite 加速。并且 fwrite 可以直接输出到屏幕上。(这与 fread 需要重定向stdin,或者用命令行里的< 不同。)更为方便的是,可以使用 sprintf 或者 vsnprintf 来方便地将一些内容写入字符数组中。下面贴上模板:

说明:你可以像 printf 和 scanf 一样使用里面的 Printf 和 Scanf 函数。但是 Scanf 函数的实现有些愚蠢(只能用%d表示一个int,并且不能有其他东西)。所以如果没有特殊需求的话最好用 Read 读取单个整数。你也可以自己写适合的 Read 函数。 输出流最后不一定需要 FlushOutput ,因为在销毁结构体的时候会执行这一步(这并不意味着你不需要fclose)。你可以通过更改 MAX_OUTPUT_ONCE 的值来更改 Printf 函数单次最大输出量。(如果超过了也许仍然能够正确输出,但那样会有一些不必要的错误。)

v0.1.0 之后提供了真正像scanf那样的读入方法。你可以用三句话实现(但是这仅仅是方便读入,并没有加速这个过程(fread带来的优化被memcpy抵消了QwQ)):

IO.Ready(); //预留足够的空间(至少为 MAX_INPUT_ONCE,不过你也需要保证一次读入的长度不超过 MAX_INPUT_ONCE)
sscanf(IO.It(), "...%n", ..., &IO.C); //读入
IO.Forward(); //刷新流,不然下一次读入会读重复的内容

注意: 结构体创建之后,就会从输入流中预读入。默认输入输出流是 stdin 和 stdout。所以不使用 FastIO 的时候请不要进行声明。

/*====================    Header : FastIO    ====================*/
/*==================== version 0.1.1 ====================*/
/*==================== Programed By chy-2003 ====================*/
/*
* Logs :
* version 0.1.1 : Fix bugs when flush input buffers
* version 0.1.0 : Add new ways to read
* new function char *It();
* new function void Ready();
* new function void Forward();
* You can read any thing like : but to make sure read less than MAX_INPUT_ONCE charactors once.
* IO.Ready();
* sscanf(IO.It(), "...%n", ..., &IO.C);
* IO.Forward();
* version 0.0.1 : Update
* change function int GetChar(); : private -> public
* new function int UnGetC(); : public (unget the last char. Return value 0:success; -1:fail)
* change function void Read(int &); : rewrite with UnGetC. will run UnGetC() after reading an integer
* version 0.0.0 : Creat
* function 'Read' and 'Scanf' will return the number of values get successfully.
* function 'Read' :
* int Read(int&);
* funtion 'Scanf' :
* Warning : This funtion works in a stupid way
* int Scanf(const char *, ...);
* supports : all(just like printf);
*
* funtion 'Printf' :
* Warning : Output may be cut off if the length longer than ((1 << 9) - 1), or you can set MAX_OUTPUT_ONCE equals to MAX_OUTPUT_BUFFER_SIZE
* void Printf(const char *, ...);
* supports : all(just like printf)
*/ #ifndef _MY_FASTIO_
#define _MY_FASTIO_ #include <cstdio>
#include <cstring>
#include <stdarg.h> #define MAX_INPUT_BUFFER_SIZE (1 << 15)
#define MAX_OUTPUT_BUFFER_SIZE (1 << 15)
#define MAX_INPUT_ONCE (1 << 9)
#define MAX_OUTPUT_ONCE (1 << 9)
//notice : I check the buffer BEFORE every option.
//notice : please make sure MAX_INPUT_BUFFER_SIZE > 2 * MAX_INPUT_ONCE struct FastIO {
//private:
char *InputBufferLeft, *InputBufferRight, InputBuffer[MAX_INPUT_BUFFER_SIZE + 1];//The last position is for '\0'
char OutputBuffer[MAX_OUTPUT_BUFFER_SIZE + 1]; // The last position is for '\0'
int OutputBufferUsed;
FILE *InputStream, *OutputStream;
char cTemp;
short iTemp;
bool CanGet; inline void ClearInputBuffer();
inline int GetFromInputStream();
inline void SetInputBufferToLeft();
inline bool EndOfFile(); public:
int C;
//Basic
FastIO(FILE *_InputStream = stdin, FILE *_OutputStream = stdout);
~FastIO(); //Input
inline int GetChar();
inline int UnGetC();
inline int Read(int &x);
inline int Scanf(const char *Format, ...);
inline void Ready();
inline void Forward();
inline char *It(); //Output
inline void FlushOutput();
inline void Printf(const char *Format, ...);
}; FastIO::FastIO(FILE *_InputStream, FILE *_OutputStream) :
InputStream(_InputStream), OutputStream(_OutputStream),
InputBufferLeft(InputBuffer), InputBufferRight(InputBuffer), OutputBufferUsed(0) {
InputBuffer[MAX_INPUT_BUFFER_SIZE] = OutputBuffer[MAX_OUTPUT_BUFFER_SIZE] = '\0';
CanGet = true;
GetFromInputStream();
return;
} FastIO::~FastIO() {
FlushOutput();
return;
} inline void FastIO::ClearInputBuffer() {
InputBufferLeft = InputBufferRight = InputBuffer;
return;
} inline int FastIO::GetFromInputStream() {
if (!CanGet) return 1;
char *Last = InputBufferRight;
InputBufferRight = InputBufferRight + fread(InputBufferRight, 1, InputBuffer + MAX_INPUT_BUFFER_SIZE - InputBufferRight, InputStream);
if (InputBufferRight == Last) CanGet = false;
return !CanGet;
} inline void FastIO::SetInputBufferToLeft() {
memcpy(InputBuffer, InputBufferLeft, InputBufferRight - InputBufferLeft);
InputBufferRight = InputBuffer + (InputBufferRight- InputBufferLeft);
InputBufferLeft = InputBuffer;
return;
} inline int FastIO::GetChar() {
if (InputBufferLeft == InputBufferRight) {
ClearInputBuffer();
if (GetFromInputStream()) return -1;
}
return *InputBufferLeft++;
} inline int FastIO::Read(int &x) {
cTemp = GetChar();
iTemp = 1;
for(; cTemp < 48 || cTemp > 57; cTemp = GetChar())
if (cTemp == -1)
return 0;
else
if (cTemp == '-')
iTemp = -1;
for(x = 0; cTemp > 47 && cTemp < 58; cTemp = GetChar())
x = (x << 3) + (x << 1) + (cTemp ^ 48);
UnGetC();
x *= iTemp;
return 1;
} inline int FastIO::Scanf(const char *Format, ...) {
int CountRead, Len, i, j;
CountRead = 0;
Len = strlen(Format);
va_list ap;
va_start(ap, Format);
for (i = 0, j; i < Len; i = j + 1) {
j = i;
while (j + 1 < Len && Format[j + 1] != '%') ++j;
if (j - i == 1 && Format[j] == 'd') {
int *x;
x = va_arg(ap, int *);
Read(*x);
++CountRead;
}
}
va_end(ap);
return CountRead;
} inline void FastIO::Ready() {
if (InputBufferRight - InputBufferLeft < MAX_INPUT_ONCE && CanGet && (InputBufferRight - InputBuffer == MAX_INPUT_BUFFER_SIZE)) {
SetInputBufferToLeft();
GetFromInputStream();
}
return;
} inline char *FastIO::It() {
return InputBufferLeft;
} inline void FastIO::Forward() {
InputBufferLeft = InputBufferLeft + C;
return;
} inline void FastIO::FlushOutput() {
if (OutputBufferUsed)
fwrite(OutputBuffer, 1, OutputBufferUsed, OutputStream);
OutputBufferUsed = 0;
return;
} inline void FastIO::Printf(const char *Format, ...) {
if (OutputBufferUsed >= MAX_OUTPUT_BUFFER_SIZE - MAX_OUTPUT_ONCE)
FlushOutput();
va_list ap;
va_start(ap, Format);
OutputBufferUsed += vsnprintf(OutputBuffer + OutputBufferUsed, MAX_OUTPUT_BUFFER_SIZE - OutputBufferUsed, Format, ap);
va_end(ap);
return;
} inline int FastIO::UnGetC() {
if (InputBuffer != InputBufferLeft) {
--InputBufferLeft;
return 0;
}
return -1;
} #undef MAX_INPUT_BUFFER_SIZE
#undef MAX_OUTPUT_BUFFER_SIZE
#undef MAX_INPUT_ONCE
#undef MAX_OUTPUT_ONCE #endif /*==================== End of Header : FastIO ====================*/

C++读入神器——文操快读(oj也可以用)的更多相关文章

  1. C++手写快读详解(快速读入数字)

    众所周知,C++里是自带读入的(这不废话吗) 例如: int a; cin>>a; 这样的读入理解简单,适合初学者,但是非常慢. 再例如: int a; scanf("%d&qu ...

  2. C/C++快读(快速读入)有多——安全AC

    在一些算法题目中中,有的程序会被卡常(数),就是说,程序虽然渐进复杂度,(通俗来讲:算法的时间复杂度)可以接受,但因为算法本身的时间常数过大,导致程序在一些算法竞赛中超时.这是,快读就显得尤为重要了. ...

  3. [C/C++]快速读入代码(快读)

    快读 1.为什么要有快读 好吧,有些题目看上去十分简单,例如https://www.luogu.com.cn/problem/P4305这道题,实际上数据量巨多,光是一个测试点就可能有几个MB,在这种 ...

  4. 快读&快写模板【附O2优化】

    快读&快写模板 快读快写,顾名思义,就是提升输入和输出的速度.在这里简单介绍一下几种输入输出的优劣. C++ cin/cout 输入输出:优点是读入的时候不用管数据类型,也就是说不用背scan ...

  5. int快读

    昨天偶然间看到CJ_tony的快读,所以便决定学习一下. 这个快读的原理就是:读入单个字符要比读入读入数字快,先读入字符,然后再转化成数字.(原理的话大学再研究) 代码: #include<io ...

  6. C++快读模板

    C++的快速读入模板 inline int read() { ; char ch = getchar(); ') { if (ch == '-') flag = true; ch = getchar( ...

  7. C++中的快读和快写

    快读原理 单个字符的读入速度要比读入数字快,因此我们以字符的形式先读入,然后处理计算转为数字. 代码 inline int read(){ register int x = 0, t = 1; reg ...

  8. 卡常三连(快读快写+re)

    快读: inline int in() { char ch; ; '))); a*=;a+=ch-'; ,a+=ch-'; return a; } 快写: inline void out(int a) ...

  9. CsvHelper文档-2读

    CsvHelper文档-2读 这个库默认不需要做任何设置就可以很容易的使用它.如果你的类属性名称直接匹配csv的标题名称,那么可以按照下面的实例来用: (以下所有的代码都需要引用using csvhe ...

随机推荐

  1. python打印带颜色的字体

    在python开发的过程中,经常会遇到需要打印各种信息.海量的信息堆砌在控制台中,就会导致信息都混在一起,降低了重要信息的可读性.这时候,如果能给重要的信息加上字体颜色,那么就会更加方便用户阅读了. ...

  2. Binding的简单使用

    Binding可以看作是数据的桥梁,两端分别为Source和Target,一般情况,Source是逻辑层的对象,Target是UI层的控件对象,可以将数据从逻辑层送往UI层展现 简单的例子: clas ...

  3. 099、如何访问Service (Swarm06)

    参考https://www.cnblogs.com/CloudMan6/p/7909136.html   前面已经学习了如何部署Service吗,也验证了swarm的failover特性,下面我们要学 ...

  4. ES6 新增的数组的方法

    给定一个数组 let list = [ // wu: 武力 zhi:智力 { id: 1, name: '张飞', wu: 97, zhi: 10 }, { id: 2, name: '诸葛亮', w ...

  5. git ignore 如何忽略已经提交的文件修改

    git ignore git ignore的作用很简单,本地仓库忽略一些文件的修改. ignore的规格可以按文件匹配,按后缀匹配或者按文件夹匹配. 如果在项目开发过程中,需要忽略某一个文件已经提交的 ...

  6. idea逆向生成hibernate工程

    1.创建maven工程 2.在resources下创建hibernate.cfg.xml文件 <?xml version='1.0' encoding='utf-8'?> <!DOC ...

  7. MySQL面试题(二)

    ● 请你说一说mysql的四种隔离状态 参考回答: Mysql主要包含四种隔离状态: 事务隔离级别 脏读 不可重复读 幻读 读未提交(read-uncommitted) 是 是 是 不可重复读(rea ...

  8. docker快速入门02——在docker下开启mysql5.6 binlog日志

    1.检查容器状态 [root@localhost ~]# docker ps 执行这个命令可以看到所有正在运行当中的容器,如果加上-a参数,就可以看到所有的容器包括停止的. 我们可以看到容器正在运行当 ...

  9. scrapy常用设置和注意点!!!!

    setting里的设置 HTTPERROR_ALLOWED_CODES = [405]   //这一条是忽略405错误退出进程,有可能跳到405页面,在parse注意判断,重新请求页面 爬虫里的设置 ...

  10. tar.xz压缩工具使用(转)

    XZ压缩最新压缩率之王 xz这个压缩可能很多都很陌生,不过您可知道xz是绝大数linux默认就带的一个压缩工具. 我是在下载phpmyadmin的时候看到这种压缩格式的,phpmyadmin压缩包xz ...