-
-
Save sfc9982/c34a68c47f5306815077a105d79dc1ca to your computer and use it in GitHub Desktop.
Code Snippets for IO Bursting in OJ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* OJ中加速IO常用的代码片段 | |
* Author Jacob C | |
* THU_ID 2014010812 | |
*/ | |
//OJ中常用的头文件和预编译指令 | |
#ifndef _OJ_ | |
#define DEBUG | |
#endif | |
#ifdef __cplusplus | |
#include <cstdio> | |
#include <cstdlib> | |
#ifdef DEBUG | |
#include <iostream> | |
using namespace std; | |
#endif | |
#else | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define true 1 | |
#define false 0 | |
typedef char bool; | |
#define newchar(n) (char*)malloc((n)*sizeof(char)) | |
#define newbool(n) (char*)malloc((n)*sizeof(char)) | |
#define newint(n) (int*)malloc((n)*sizeof(int)) | |
#define newuint(n) (unsigned int*)malloc((n)*sizeof(unsigned int*)) | |
#endif | |
typedef unsigned int uint; | |
typedef long long int llint; | |
typedef unsigned long long int ullint; | |
//缓冲区大小设置 | |
#ifndef BUFFER_SIZE | |
#warning "buffer size is set to 1<<20, max size that doesn't cause stack overflow is 26" | |
#define BUFFER_SIZE 20 | |
#endif | |
//定义BURST_IO为使用自定义类fastio加速(使用fread),不定义BURST_IO则为setvbuf方式的自定义类加速 | |
#ifdef BURST_IO | |
/***** fread版本 *****/ | |
#ifdef __cplusplus | |
//C++版本 fread 从http://www.cnblogs.com/jklongint/p/4774075.html更改而来 | |
class fastio | |
{ | |
public: | |
fastio() | |
{ | |
in = new char[insize]; | |
out = new char[outsize]; | |
pin = in; | |
countin = countout = 0; | |
sin = stdin; | |
sout = stdout; | |
read2mem(); | |
} | |
fastio(FILE *fin, FILE *fout) | |
{ | |
in = new char[insize]; | |
out = new char[outsize]; | |
pin = in; | |
countin = countout = 0; | |
sin = fin; | |
sout = fout; | |
} | |
~fastio() | |
{ | |
write2disk(); | |
} | |
int read2mem() | |
{ | |
return countin = fread(in, 1, insize, sin); | |
fclose(sin); | |
} | |
int write2disk() | |
{ | |
return fwrite(out, 1, countout, sout); | |
fclose(sout); | |
} | |
int read() { return 0; } | |
template<typename T, typename ...R> int read(T &f, R &...r) | |
{ | |
if (get(f) == -1) return -1; | |
c = read(r...); | |
if (c == -1) return -1; | |
return 1 + c; | |
} | |
void write() | |
{ | |
put('\n'); | |
} | |
template<typename T, typename ...R> void write(const T x, const R ...r) | |
{ | |
put(x); | |
write(r...); | |
} | |
private: | |
const static int insize = (1 << BUFFER_SIZE), outsize = (1 << BUFFER_SIZE); //放在堆上最大为18 | |
char *in, *out, *pin; //使用如char in[insize]这样的静态声明可能会导致爆栈 | |
FILE *sin, *sout; | |
int countin, countout, a[20], c, negative; | |
/*** read的实现 ***/ | |
inline bool digit(const char ch) | |
{ | |
return ch == '-' || ch >= '0' && ch <= '9'; | |
} | |
int get(char s[]) | |
{ | |
while ((*pin == ' ' || *pin == '\n') && pin - in != countin) pin++; | |
if (pin - in == countin) return -1; | |
while (*pin != ' ' && *pin != '\n' && pin - in != countin) *s++ = *pin++; | |
*s = 0; | |
return 1; | |
} | |
int get(char &ch) | |
{ | |
if (pin - in == countin) return -1; | |
ch = *pin++; | |
return 1; | |
} | |
int get(int &buf) | |
{ | |
while (!digit(*pin) && pin - in != countin) pin++; | |
if (pin - in == countin) return -1; | |
buf = 0; | |
negative = 0; | |
if (*pin == '-') | |
{ | |
negative = 1; | |
pin++; | |
} | |
while (digit(*pin) && pin - in != countin) | |
{ | |
buf = buf * 10 + *pin - '0'; | |
pin++; | |
} | |
if (negative) buf = -buf; | |
return 1; | |
} | |
int get(uint &buf) | |
{ | |
while (!digit(*pin) && pin - in != countin) pin++; | |
if (pin - in == countin) return -1; | |
buf = 0; | |
while (digit(*pin) && pin - in != countin) | |
{ | |
buf = buf * 10 + *pin - '0'; | |
pin++; | |
} | |
return 1; | |
} | |
/*** write的实现 ***/ | |
void put(uint x) | |
{ | |
c = 0; | |
a[c++] = x % 10 + '0'; | |
x /= 10; | |
while (x) | |
{ | |
a[c++] = x % 10 + '0'; | |
x /= 10; | |
} | |
while (c) | |
{ | |
out[countout++] = a[--c]; | |
} | |
} | |
void put(int x) | |
{ | |
c = 0; | |
negative = x < 0; | |
if (negative) | |
{ | |
x = -x; | |
out[countout++] = '-'; | |
} | |
a[c++] = x % 10 + '0'; | |
x /= 10; | |
while (x) | |
{ | |
a[c++] = x % 10 + '0'; | |
x /= 10; | |
} | |
while (c) | |
{ | |
out[countout++] = a[--c]; | |
} | |
} | |
void put(const char &ch) | |
{ | |
out[countout++] = ch; | |
} | |
void put(char s[]) | |
{ | |
while (*s) out[countout++] = *s++; | |
} | |
void put(const char s[]) | |
{ | |
while (*s) out[countout++] = *s++; | |
} | |
}; | |
#else | |
//C语言版本 fread | |
#warning "C version fastio has not implemented output, use printf instead." | |
typedef struct iobuf_t { | |
char* inbuf; | |
char* countin; | |
char* pin; | |
char* outbuf; | |
int countout; | |
}fastio; | |
fastio* initio() | |
{ | |
const int SZ = 1 << BUFFER_SIZE; //IO buff的大小 | |
fastio* buf = (fastio*)malloc(sizeof(fastio)); | |
buf->inbuf = newchar(SZ); | |
buf->outbuf = newchar(SZ); | |
buf->countin = fread(buf->inbuf, 1, SZ, stdin) + buf->inbuf; | |
buf->pin = buf->inbuf; | |
buf->countout=0; | |
return buf; | |
} | |
void finishio(fastio *buf) | |
{ | |
return fwrite(buf->outbuf, 1, buf->countout, stdout); | |
fclose(stdout); | |
} | |
bool digit(const char ch) | |
{ | |
return ch == '-' || ch >= '0' && ch <= '9'; | |
} | |
uint getu(fastio *buf) | |
{ | |
uint val = 0; | |
while (!digit(*(buf->pin)) && buf->pin != buf->countin) buf->pin++; | |
while (digit(*(buf->pin)) && buf->pin != buf->countin) | |
{ | |
val = val * 10 + *(buf->pin) - '0'; | |
buf->pin++; | |
} | |
return val; | |
} | |
void putu(fastio *buf, uint x) | |
{ | |
char a[20]; | |
int c = 0; | |
a[c++] = x % 10 + '0'; | |
x /= 10; | |
while (x) | |
{ | |
a[c++] = x % 10 + '0'; | |
x /= 10; | |
} | |
while (c) | |
{ | |
buf->outbuf[buf->countout++] = a[--c]; | |
} | |
buf->outbuf[buf->countout++] = '\t'; | |
} | |
#endif | |
#else | |
/***** setvbuf版本 *****/ | |
#ifdef __cplusplus | |
//C++版本 setvbuf | |
const int SZ = 1 << BUFFER_SIZE; //提升IO buff | |
struct fastio { | |
char inbuf[SZ]; | |
char outbuf[SZ]; | |
fastio() | |
{ | |
setvbuf(stdin, inbuf, _IOFBF, SZ); | |
setvbuf(stdout, outbuf, _IOFBF, SZ); | |
} | |
}io; | |
#else | |
//C语言版本 setvbuf | |
void burstio() | |
{ | |
const int SZ = 1 << BUFFER_SIZE; //提升IO buff | |
char *inbuf = (char*)malloc(SZ * sizeof(char)); | |
char *outbuf = (char*)malloc(SZ * sizeof(char)); | |
setvbuf(stdin, inbuf, _IOFBF, SZ); | |
setvbuf(stdout, outbuf, _IOFBF, SZ); | |
} | |
#endif | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment