本文会介绍一些我所知道的小技巧,但是受限于noip,比赛不能用的技巧我都不会提及
首先要介绍的就是快读和快写,众所周知,cin和cout是比scanf和printf慢的,但是如果还要进一步提升速度,就必须使用快读和快写,快读和快写的原理就是,在处理字符的时候,比处理数字更快,当然还有一种更快的,fread,但是写法很复杂,用途也没那么广,所以快读和快写是比较广泛的选择
int read() //快速读入
{
int s = 0, f = 1;
char ch = getchar(); //getchar是灵魂,没有这个玩意儿也就没有快读
while(!isdigit(ch)) //本文用了isdigit函数
//它的效率和手写ascll码判断不相上下,有时候还会更快
{
if(ch == '-') f = -1; //如果这个数字的第一个字符不是数字,那就肯定是-号啦
//应该没有谁会在正数面前写+号的吧,所以变成负的,到时候输出负数
ch = getchar();
}
while(isdigit(ch)) //当读入的值是数字的时候
//让s当前存的值进位,然后让最低位加上新读入的值
{
s = s * 10 + ch - '0';
ch = getchar();
}
return s * f;
}
void write(int x) //快写
{
if(x < 0)
{
putchar('-');
x = -x;
}
if(x > 9)
{
write(x/10);
}
putchar(x % 10 - '0'); //快写的灵魂
return;
}
使用方法就是,变量=read();write(变量);
当然你也可以自己改
下面给一种能自动判断类型的快读
template <typename T>
void read(T &x) {
x = 0;
int f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') f = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + (ch ^ 48);
ch = getchar();
}
x *= f;
return;
}
输入输出部分也就结束了
然后要说的是,可以在函数前面加上inline函数,这的东西是告诉程序,在运行函数的时候把它打印到代码里,能提高代码的效率,如果有用会加快代码效率,如果没用,那跟原来的速度也没差
还有,取模运算的复杂度比较高,能不用就尽量不用,还有就是,如果是特定的2的n次方,比如2,8,10,16这几个可以写成n&1,n&7,n&9,n&15来代替取模运算,比取模更快
i++可以写成++i,虽然听说i++会被编译器优化,但是我还是写出来比较好,毕竟我知道的优化技巧不多
还有平方写成a*a比pow快
以及用左移和右移代替乘2和除2的操作,特别是除法,最慢了
还有循环层次最多的那层,如果可以,尽量放到最里面
还有一些二进制的奇技淫巧,一并放在这里
inline int abs(int x)
{
int y=x>>31;
return (x+y)^y;
}//计算绝对值
inline int max(int x,int y)
{
int m=(x-y)>>31;
return (y&m)|(x&~m);
}//求最大值
inline void swap(int &x,int &y)
{
x^=y,y^=x,x^=y;
}//交换两个数,神奇吧,这样就可以不用第三个空间了
文章就到这里吧,感谢观看