Note
注意,如果您有正确使用freadfwrite的能力,请拆开此模板,使用裸的freadfwrite。本模板为了安全性和完整性包装了许多东西,虽然加了很多常数优化,直接使用freadfwrite还是会更快。
有些人说本模板太长,我在这里做出统一答复:模板长是因为要实现全面的操作和维护使用安全性,只需要记忆getch和putch函数以代替getchar和putchar就行。还嫌长那就先去把getchar和putchar学会吧。
所以要记忆本模板时,比起普通的快速读写只需要多记忆2个函数而已,getch和putch。
本文在github的链接:https://github.com/huanghaox1212/FastIO
Updates
u p d a t e 1 : update1: update1:应某用户建议,已将模板改为 c l a s s class class。
u p d a t e 2 : update2: update2:某用户发现 p u t s puts puts函数运行效率存在问题,已更正。
u p d a t e 3 : update3: update3:应某用户建议,已修改 g o go go函数至析构函数。
u p d a t e 4 : update4: update4:为防止用户使用错误,将 F a s t I O FastIO FastIO的对象的定义置于模板中。
u p d a t e 5 : update5: update5:删去了 r f i l e rfile rfile和 w f i l e wfile wfile。
u p d a t e 6 : update6: update6:应某用户建议,输出 s t r i n g string string的函数参数类型改为了 c o n s t s t r i n g & const\ string\& const string&。
u p d a t e 7 : update7: update7:经核实发现本模板在效率方面有一些问题,进行了全面修改,并加入_endl和_prs和_setprecision等控制类型。
详情请参照正文。
如果您按照指定方法使用仍然存在bug,请私信我。
正文
黑科技,稳定、高效率且全面+疯狂常数优化的模板。
D e v C p p 5.11 + S a m s u n g W i n d o w s 7 DevCpp5.11+Samsung\ Windows7 DevCpp5.11+Samsung Windows7环境下评测,(编译后运行)读入并输出1802KB字符,本模板耗时1.27ms, g e t c h a r getchar getchar和 p u t c h a r putchar putchar耗时1524.67ms, c i n c o u t cincout cincout和 s c a n f p r i n t f scanfprintf scanfprintf直接崩溃。
首先模板献上:
(注意:为避免错误使用,使用前一定要查看后面的使用说明)
#include<bits/stdc++.h>
using namespace std;
#define reg register
struct control{
int ct,val;
control(int Ct,int Val=-1):ct(Ct),val(Val){}
inline control operator()(int Val){
return control(ct,Val);
}
}_endl(0),_prs(1),_setprecision(2);
struct FastIO{
#define IOSIZE 1000000
char in[IOSIZE],*p,*pp,out[IOSIZE],*q,*qq,ch[20],*t,b,K,prs;
FastIO():p(in),pp(in),q(out),qq(out+IOSIZE),t(ch),b(1),K(6){}
~FastIO(){fwrite(out,1,q-out,stdout);}
inline char getch(){
return p==pp&&(pp=(p=in)+fread(in,1,IOSIZE,stdin),p==pp)?b=0,EOF:*p++;
}
inline void putch(char x){
q==qq&&(fwrite(out,1,q-out,stdout),q=out),*q++=x;
}
inline void puts(const char str[]){fwrite(out,1,q-out,stdout),fwrite(str,1,strlen(str),stdout),q=out;}
inline void getline(string& s){
s="";
for(reg char ch;(ch=getch())!='\n'&&b;)s+=ch;
}
#define indef(T) inline FastIO& operator>>(T& x){\
x=0;reg char f=0,ch;\
while(!isdigit(ch=getch())&&b)f|=ch=='-';\
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getch();\
return x=f?-x:x,*this;\
}
indef(int)
indef(long long)
inline FastIO& operator>>(char& ch){return ch=getch(),*this;}
inline FastIO& operator>>(string& s){
s="";reg char ch;
while(isspace(ch=getch())&&b);
while(!isspace(ch)&&b)s+=ch,ch=getch();
return *this;
}
inline FastIO& operator>>(double& x){
x=0;reg char f=0,ch;
double d=0.1;
while(!isdigit(ch=getch())&&b)f|=(ch=='-');
while(isdigit(ch))x=x*10+(ch^48),ch=getch();
if(ch=='.')while(isdigit(ch=getch()))x+=d*(ch^48),d*=0.1;
return x=f?-x:x,*this;
}
#define outdef(_T) inline FastIO& operator<<(_T x){\
!x&&(putch('0'),0),x<0&&(putch('-'),x=-x);\
while(x)*t++=x%10+48,x/=10;\
while(t!=ch)*q++=*--t;\
return *this;\
}
outdef(int)
outdef(long long)
inline FastIO& operator<<(char ch){return putch(ch),*this;}
inline FastIO& operator<<(const char str[]){return puts(str),*this;}
inline FastIO& operator<<(const string& s){return puts(s.c_str()),*this;}
inline FastIO& operator<<(double x){
reg int k=0;
this->operator<<(int(x));
putch('.');
x-=int(x);
prs&&(x+=5*pow(10,-K-1));
while(k<K)putch(int(x*=10)^48),x-=int(x),++k;
return *this;
}
inline FastIO& operator<<(const control& cl){
switch(cl.ct){
case 0:putch('\n');break;
case 1:prs=cl.val;break;
case 2:K=cl.val;break;
}
}
inline operator bool(){return b;}
}io;
原理:每次批量读入1000001字节,存到输入项里,读完了继续尝试读入,存到输入项里。每次批量输出1000001字节,最后用析构函数把输出项里剩下的也输出了。如果觉得空间会超限(大约2KB的读写数组,超限的可能还是很小的),请自行调整批量读写的数据大小。
使用说明:
1.本模板的文件流没有兼容用其他的任何输入/输出,包括getchar、putchar、cin、scanf之类。一般情况下该模板足以实现常用的读写功能,如果仍然有特殊需求,请自行添加功能。
2.FastIO的定义必须为全局变量。为了防止有人误用,已经加在模板里,请勿多此一举在代码里写出FastIO io的定义。
3.具体用法如下:
· 预处理
#include <bits/stdc++.h>//头文件不要乱改,否则会不支持某些函数。
using namespace std;
//在此处,即using语句的下一句加入模板。
//other defines.
int main(){
freopen(输入文件名,"r",stdin),freopen(输出文件名,"w",stdout);
//注意在标准输入输出评测时去掉freopen语句
//调试时一定要用文件读写,否则输入会卡死(评测机上不会)。
//由于所有评测机本质上皆使用文件式评测,无需担心会在评测机上出错(亲测通过Luogu和OJ评测)。
return 0;
}
· 输入输出
char ch;int a;long long d;string s1,s2;double aa,bb;
io>>ch>>a>>d>>s1>>aa>>bb,io<<ch<<a<<d<<s1<<aa<<bb;
io.getline(s2),io<<s2,io.puts("123"),io<<"456";
//<<输出操作不能与>>输入操作连在一起!
· 判断EOF(使用重载类型转换运算符实现)
while(io>>ch)io<<ch;//判断方法与cin类似。
if(io)...
· 控制类型的使用
io<<_endl;//换行
io<<_prs(true);//从现在开始,一律选择进行四舍五入
io<<_prs(false);//从现在开始,一律不进行四舍五入
io<<_setprecision(k);//从现在开始,一律保留k位小数
//注意:控制类型仅为方便习惯于iostream的用户来使用,平时尽量不要用,否则会对效率进行影响。
· 其他
//那个模板中,可以把不要的重载运算符删掉,比如只需要输入输出整数,就把输入输出字符串之类的删掉。
//如果需要别的实现,请以getch和putch代替getchar和putchar,然后自行实现。
//以下几个函数/变量千万不能删掉:
//FastIO,~FastIO,getch,putch,in,out,p,pp,q,qq
//有时编译时可能会有警告,不用担心,可放心使用。
//警告原因:
//1.输出C风格字符串的函数参数是const类型,输出字符串变量时会警告。
//2.为了常数优化,部分int换成了char,某些编译器会进行警告。