第一篇uoj博客~
相信很多同学都喜欢cin,cout的方便,却因为cin,cout的常数太大而常常弃之不用,所以经常会写上输入输出优化,很多同学甚至嫌输入输出优化麻烦直接用scanf,printf了
所以我的这个模板强行把常数小的fread,fwrite套在了结构体里,并给结构体赋予了>>,<<运算符,常数方便两不误!(当然是指刷题)
因为为了代码的整齐度之类的(写的比较全,强迫症),并没有去搞什么更奇技淫巧的优化了,所以常数可能相对于大神来说,会偏大???
特别地,我的浮点数输入对于1e-6,2.1e-3这种能够接受,为什么呢?因为一次模拟赛,出题人卡输入的常数,结果又是用cout造的数据,什么意思?你们可以尝试一下
std::cout<<0.0000001<<std::endl;
然后我那天一直以为被卡精度,结果(mmp)。。。。于是我在板子上加了这个。
总的来说有以下优点:
1.使用方便(对于喜爱文件读入读出的同学更开心了,喜爱控制台的可就不那么好接受了--)//什么你觉得断点输出很麻烦?SF会查不出来?试试cerr吧!
2.速度客观 略快于一般的getchar的读入优化(常数大师的除外,常数大师可能不用getchar吧?),远快于std的cin,cout
3.输入输出较为齐全,适用于绝大部分题目
4.支持多文件输入,你可以直接用FILE *fp = fopen 打开一个新的文件然后io::filein fin(fp); fin.in()就好啦!是不是很方便呢
有以下缺点:
1.double,float的输出不够优美,我是用sprintf的,因为单单的写四舍五入乘法除法浮点数的效率已经和printf差不了多少了,所以直接上了sprintf,速度还是灰常快滴(你同样也可以用cout.bit(x)来将其改为保留小数点后x位)
2.不支持long double的输出(感觉也很少用。。。其实是我不是很会写...0.0)
希望各路大神不喜勿喷,喜欢的同学可以拿去尝试一下,有什么意见和bug可以在评论区告诉我,谢谢。
更新: 2017.8.18 内容:将文件内置于两个结构体中,并通过一个宏变量LOCAL来决定是否打开文件,从本地交题到OJ上请删除或者注释掉#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cassert>
#include <cmath>
#include <complex>
#include <bitset>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define rep(i, a, b) for(rg int (i) = (a), __omega = (b); (i) <= __omega; ++(i))
#define down(i, a, b) for(rg int (i) = (a), __omega = (b); (i) >= __omega; --(i))
#define run(x) for(rg int __omega = (x); __omega; --__omega)
#define cmax(i, j) ((i) < (j) ? (i) = (j) : (i))
#define cmin(i, j) ((i) > (j) ? (i) = (j) : (i))
#define dmax(i, j) ((j) < (i) ? (i) : (j))
#define dmin(i, j) ((i) < (j) ? (i) : (j))
#define dabs(i) ((i) > 0 ? (i) : -(i))
#define cabs(i) ((i) < 0 ? (i) = -(i) : (i))
#define dsqr(i) ((i)*(i))
#define rg register
#define int64 long long
#define uint unsigned int
#define uint64 unsigned long long
namespace io {
const int IO_size = 1<<25;
struct filein {
char B[IO_size], *S;
FILE *file;
inline void operator = (rg FILE *f) { file = f; }
filein(FILE *f = NULL) { S = B; if(f) *this = stdin; }
void setfile(const char *filename) { file = fopen(filename, "r"); in(); }
void closefile() { fclose(file); }
inline void in() { fread(B, 1, IO_size, file); }
template<typename type>
inline type read_int() {
rg type aa; rg char cc;
for(; (*S < 48 || *S > 57) && *S != '-'; S++);
cc = *S == '-' ? (S++, 0) : 1, aa = *S++-48;
for(; *S >= 48 && *S <= 57; S++) aa = (aa<<1)+(aa<<3)+*S-48;
cc ? : aa = -aa; return aa;
}
template<typename type>
inline type read_float() {
rg type aa, bb = 0, gg = 1; rg char cc;
rg char ch;
for(; (*S < 48 || *S > 57) && *S != '-'; S++);
cc = *S == '-' ? (S++, 0) : 1, aa = *S++-48;
for(; *S >= 48 && *S <= 57; S++) aa=aa*10+*S-48;
if(*S == 'e') {
bb += aa; aa = 0;
S++; int k = read_int<int>();
if(k < 0) while(k) bb /= 10, k++;
else while(k) bb *= 10, k--;
}
if(*S == '.') {
for(S++; *S >= 48 && *S <= 57; S++)
bb += (*S-48)*(gg /= 10);
if(*S == 'e') {
bb += aa; aa = 0;
S++; int k = read_int<int>();
if(k < 0) while(k) bb /= 10, k++;
else while(k) bb *= 10, k--;
}
}
aa += bb, cc ? : aa = -aa;
return aa;
}
inline char getc() { return *S++; }
inline void gets(rg char *s) {
for(; *S == ' ' || *S == '\n'; S++);
for(; *S != ' ' && *S != '\n' && ~*S && *S; *s++ = *S++);
*s++ = '\0';
}
} cin(stdin);
struct fileout {
char U[IO_size], *O, bit_float[20], bit_double[20];
FILE *file;
inline void operator = (rg FILE *f) { file = f; }
fileout(FILE *f = NULL) { O = U; bit(6); if(f) *this = f;}
void setfile(const char *filename) { file = fopen(filename, "w"); }
void closefile() { out(); fclose(file); }
inline void out() { fwrite(U, 1, O-U, file), O = U; }
template<typename type>
inline void write(rg type a) {
static char stack[50];
rg int i = 0;
if(!a) { *O++ = 48; return; }
a < 0 ? a = -a, *O++ = '-' : 1;
for(; a; a /= 10) stack[++i] = a%10;
for(; i; *O++ = stack[i--]+48);
}
inline void bit_f(rg int len) {
rg char *it = bit_float;
*it++ = '%', *it++ = '.';
if(len > 9) *it++ = len/10+48, *it++ = len%10+48;
else *it++ = len+48;
*it++ = 'f';
*it++ = '\0';
}
inline void bit_d(rg int len) {
rg char *it = bit_double;
*it++ = '%', *it++ = '.';
if(len > 9) *it++ = len/10+48, *it++ = len%10+48;
else *it++ = len+48;
*it++ = 'l', *it++ = 'f';
*it++ = '\0';
}
inline void bit(rg int len) { bit_f(len), bit_d(len); }
inline void write_float(rg float a) { O += sprintf(O, bit_float, a); }
inline void write_double(rg double a) { O += sprintf(O, bit_double, a); }
inline void putc(rg char c) { *O++ = c; }
inline void puts(rg const char *s) { for(; *s; s++) *O++ = *s; }
} cout(stdout);
inline filein& operator >> (rg filein& _in, rg int& x) { x = _in.read_int<int>(); return _in; }
inline filein& operator >> (rg filein& _in, rg int64& x) { x = _in.read_int<int64>(); return _in; }
inline filein& operator >> (rg filein& _in, rg uint& x) { x = _in.read_int<uint>(); return _in; }
inline filein& operator >> (rg filein& _in, rg uint64& x) { x = _in.read_int<uint64>(); return _in; }
inline filein& operator >> (rg filein& _in, rg char& ch) { ch = _in.getc(); return _in; }
inline filein& operator >> (rg filein& _in, rg char *s) { _in.gets(s); return _in; }
inline filein& operator >> (rg filein& _in, rg float& x) { x = _in.read_float<float>(); return _in; }
inline filein& operator >> (rg filein& _in, rg double& x) { x = _in.read_float<double>(); return _in; }
inline filein& operator >> (rg filein& _in, rg long double& x) { x = _in.read_float<long double>(); return _in; }
inline fileout& operator << (rg fileout& _out, rg int x) { _out.write<int>(x); return _out; }
inline fileout& operator << (rg fileout& _out, rg int64 x) { _out.write<int64>(x); return _out; }
inline fileout& operator << (rg fileout& _out, rg uint x) { _out.write<uint>(x); return _out; }
inline fileout& operator << (rg fileout& _out, rg uint64 x) { _out.write<uint64>(x); return _out; }
inline fileout& operator << (rg fileout& _out, rg char ch) { _out.putc(ch); return _out; }
inline fileout& operator << (rg fileout& _out, rg const char *s) { _out.puts(s); return _out; }
inline fileout& operator << (rg fileout& _out, rg float x) { _out.write_float(x); return _out; }
inline fileout& operator << (rg fileout& _out, rg double x) { _out.write_double(x); return _out; }
const char endl = '\n';
}
namespace work_space {
#define LOCAL
using namespace io;
void main() {
rg int a, b;
cin >> a >> b;
cout << a+b << endl;
}
}
#ifdef LOCAL
#define setfile(s) io::cin.setfile(s".in"), io::cout.setfile(s".out")
#define closefile() io::cin.closefile(), io::cout.closefile()
#else
#define setfile(s) io::cin.in()
#define closefile() io::cout.out()
#endif
#define filename "data"
int main() {
setfile(filename);
work_space::main();
closefile();
return 0;
}