快读与快输(读入优化与输出优化、QIO优化)
1、常规读入优化与输出优化
1.1读入
利用getchar()加快读入
int res, f;
inline int read(int &ret)
{
ret = 0, f = 1;
char ch = getchar();
while (ch<'0' || ch > '9')
{
if (ch == '-')
f = -f;
ch = getchar();
}
while (ch >= '0'&&ch <= '9')
{
ret = ret * 10 + ch - '0';
ch = getchar();
}
ret *= f;
}
1.2多参数快读
没别的,就好用
template<typename T>inline void read(T &t)
{
ri c = getchar(); t = 0;
while (!isdigit(c))
c = getchar();
while (isdigit(c))
t = t * 10 + c - 48, c = getchar();
}
template<typename, typename... Args>
inline void read(T&t, Args&...args)
{
read(t); read(args...);
}
1.3快输
其实printf就已经很快了,没必要用快输
void write(int x)
{
if (x < 0)
{
putchar('-'); x = -x;
}
int y = 10, len = 1;
while (y <= x)
{
y *= 10;
len++;
}
while (len--)
{
y /= 10;
putchar(x / y + 48);
x %= y;
}
}
2、利用fread和fwrite的快读与快输
2.1fread的快读
fread可以快速读入大量数据(<cctype>)
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline int getc() {
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline int read()
{
int ret = 0, f = 0;
char ch = getc();
while (!isdigit(ch)) {
if (ch == '-')
f = 1;
ch = getc();
}
while (isdigit(ch)) {
ret = ret * 10 + ch - 48;
ch = getc();
}
return f ? -ret : ret;
}
2.2fwrite的快输
printf虽然比较快,但是大量输出数据的时候fwrite可以快速输出
char buf[1 << 21], a[20]; int p, p2 = -1;
inline void flush() {
fwrite(buf, 1, p2 + 1, stdout);
p2 = -1;
}
inline void print(int x) {
if (p2 > 1 << 20) flush();
if (x < 0) buf[++p2] = 45, x = -x;
do {
a[++p] = x % 10 + 48;
} while (x /= 10);
do {
buf[++p2] = a[p];
} while (--p);
buf[++p2] = '\n';//接一个后序的格式符,也可以没有
}
//程序结束前一定要再调用一次flush
3、QIO(IO优化类)
class QIO {
public:
char buf[1 << 21], * p1 = buf, * p2 = buf;
int getc() {
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
int read() {
int ret = 0, f = 0;
char ch = getc();
while (!isdigit(ch)) {
if (ch == '-')
f = 1;
ch = getc();
}
while (isdigit(ch)) {
ret = ret * 10 + ch - 48;
ch = getc();
}
return f ? -ret : ret;
}
char Buf[1 << 21], out[20];
int P, Size = -1;
void flush() {
fwrite(Buf, 1, Size + 1, stdout);
Size = -1;
}
void write(int x, char ch) {
if (Size > 1 << 20) flush();
if (x < 0) Buf[++Size] = 45, x = -x;
do {
out[++P] = x % 10 + 48;
} while (x /= 10);
do {
Buf[++Size] = out[P];
} while (--P);
Buf[++Size] = ch;
}
};
更详细的
#pragma once
#include <iostream>
#include <cstdio>
#include <cctype>
#include <stdlib.h>
using namespace std;
typedef long long LL;
class QIO { //常规的快读和快输
public:
//利用fread加快读取速度
QIO();
~QIO();
LL read(); //stdin读入LL
void read(char *str); //stdin读入char*
void getinfile(FILE *file); //读入文件
void closeinfile(); //关闭文件
int getc(); //getchar
LL readlld(); //文件读入LL
LL readnum(int l); //文件读入指定长度number
//利用fwrite加快输出速度
void getoutfile(FILE *file) //读入输出文件
{
filp = file;
}
void closeoutfile() //关闭输出文件
{
fclose(filp);
}
void flush(); //fwrite输出
void write(LL x, char ch); //文件输出LL
void write(char *s, char ch); //文件输出char*
private:
char buf[1 << 21], *p1, *p2; //fread串
FILE *fp; //读入文件指针
char BUF[1 << 21], outnum[20]; //fwrite串
int Size = -1, p;
FILE *filp; //输出文件指针
};
#include "QIO.h"
QIO::QIO()
{
Size = -1;
p = 0;
p1 = p2 = buf;
fp = filp = NULL;
}
QIO::~QIO()
{
delete p1;
delete p2;
delete fp;
delete filp;
}
LL QIO::read()
{
LL ret = 0, f = 1;
char ch = getchar();
while (ch<'0' || ch>'9')
{
if (ch == '-')
f = -f;
ch = getchar();
}
while (ch >= '0'&&ch <= '9')
ret = ret * 10 + ch - '0',
ch = getchar();
return ret * f;
}
void QIO::read(char *str)
{
char ch; int g = 0;
ch = getchar();
while (ch == ' ' || ch == '\n')
ch = getchar();
while (ch != '\n')
{
str[g++] = ch;
ch = getchar();
}
str[g] = '\0';
}
void QIO::getinfile(FILE *file)
{
if (!file)
{
printf("文件打开失败,请重试.\n");
exit(1);
}
fp = file;
}
void QIO::closeinfile()
{
fclose(fp);
}
int QIO::getc()
{
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, fp), p1 == p2) ? EOF : *p1++;
}
LL QIO::readlld() {
LL ret = 0, f = 0;
char ch = getc();
while (!isdigit(ch)) {
if (ch == '-')
f = 1;
ch = getc();
}
while (isdigit(ch)) {
ret = ret * 10 + ch - 48;
ch = getc();
}
return f ? -ret : ret;
}
LL QIO::readnum(int l) {
char ch = getc();
while (!isdigit(ch))
ch = getc();
LL ret = ch - 48;
for (int i = 1; i < l; ++i)
{
ch = getc();
ret = ret * 10 + ch - 48;
}
return ret;
}
void QIO::flush()
{
fwrite(BUF, 1, Size + 1, filp);
Size = -1;
}
void QIO::write(LL x, char ch) {
if (Size > 1 << 20) flush();
if (x < 0) BUF[++Size] = 45, x = -x;
do {
outnum[++p] = x % 10 + 48;
} while (x /= 10);
do {
BUF[++Size] = outnum[p];
} while (--p);
BUF[++Size] = ch;
}
void QIO::write(char *s, char ch) {
if (Size > 1 << 20) flush();
int i = 0;
while (s[i] != '\0') {
BUF[++Size] = s[i];
i++;
}
BUF[++Size] = ch;
}