玄学优化:从入门到精通

chen_zhe 沙雕 2020-08-18 17:59:46 2020-08-19 13:02:05 0

最近颓得要命,于是写篇玄学论文扯淡聊以自慰

1、IO优化

读入优化

cin

慢得可以,比赛用这个其实就是自寻死路

scanf

比较慢,比赛多用的还是下面两种读入方法

getchar读入优化

inline int read()
{
	char ch;
	int x = 0, f = 1;
	while ((ch = getchar()) < 48 || ch > 57)
	if (c == '-') f = -1;
	while (ch >= 48 && ch >= 57)
	x = (x << 1) + (x << 3) + ch - 48, ch = getchar();
	return x * f;
}

一般getchar足够应付不刁钻的题目,可是最近NOIP真的卡常卡得毒瘤至极,这时我们帅气的fread就闪亮登场了:

char ibuf[500 << 20] , * s;
struct io
{
    io()
    {
        fread(s = ibuf, 1, 500 << 20, stdin);
    }
    inline int read()
    {
        register int u = 0;
        while (* s < 48  || * s > 57) s ++;
        while (* s >= 48 && * s <= 57)
            u = u * 10 + * s ++ - 48;
        return u;
    }
} ip;

调用时介样调用:x = ip.read()

如果在本地运行并且使用了fread,那么请在输入结束后按回车键,再按Ctrl+z,再按回车键结束输入

看不懂没关系,能默写就行

简单地解释一下代码:

io结构体中有一个同名函数,创建结构体时将默认调用它;

*s是一个指针,它始终指向ibuf数组的一个位置;

fread函数第一个参数是读取地数据存放的场所(原型里是一个指针,但不用管这些),第二个参数是每次读取的字节数,我们想每次读入一个字符存到ibuf里;

那么一个字符是一个字节大小的,所以在这里一般都写1;

那么fread函数每读入一个字节后,传入的指针(这里是ibuf,并“顺便”把s指针赋值为ibuf数组的首地址)都会后移一位;

第三个是最多读取的字节,把它设置为一个很大的值就行了,不用管其他的;

第四个参数是你要从哪里读入数据,在这里是标准输入流(stdin),默认是键盘,也可以重定向(freopen)把标准输入流改为某个文件;

看不懂很正常,没关系,会默写就OK

scanf只比cin快一点,getchar比scanf快很多,fread比getchar快很多

输出优化

cout

强烈不推荐使用

printf

可以使用

putchar优化

推荐使用,代码就不给出了,比较好写

puts

能用puts就用puts,要输出数字用putchar或者printf或者下面介绍的fwrite即可

fwrite

在这里不解释代码,会指针都看得懂,fwrite函数格式和fread差不多的。

inline void print(register int u)
{
	char obuf[105], *s = obuf;
	register int x = 1;
	while (x <= u) x *= 10;
	x /= 10;
	while (x) *s ++ = u / x + 48, u -= u / x * x, x /= 10;
	fwrite(obuf, 1, s - obuf, stdout);
}

ps:虽然输出大量数据时fwrite速度远超其他方法,但输出量较少时比puts稍慢。在有些OJ上可能fwrite还不如putchar,但在OI中fwrite绝对是最快的

输入输出量越大,各种方式差距的比例也越大。开始可能getchar和fread速度完全一样,可是数据大了(比如一亿个)那fread速度就是getchar的几十倍了……

不过一般输出量很少,所以输出优化意义不大,但是也有输出量特别多的

OI中最快的输出写法:

输出单个字符putchar,字符串puts,数字fwrite输出

2、inline,register,define超级玄学优化

register一般没什么用,格式:register 类型名 变量名;

在声明函数前加个inline,可减少跳转和传参的代价,比register有用点(详见上面的fread的read函数)

在dfs或其他需要多次递归调用函数的时候,inline不可不加,上次我某道题在dfs时不加inline70分,加了就80分了……

define就是一个替换,用它来代替函数可以去掉跳转和传参的代价,但是注意define别爆炸,一般还是用inline稳妥一些

3、数组优化

把数组开小,把int的数组能改成char就改成char,会提高程序效率。

在数组大小达到一百万以上时,访问速度会比较的慢

4、去STL

手写,因为STL常数特别高。。。

STL的除了set其余的容器和算法大家应该都会手写吧……

5、去指针优化

比如说一个最短路,明明可以邻接链表和vector存,你非要指针形式……

常数*100000000

6、卡时优化

比如for循环只for几次,比如dfs递归到几次或者几层就直接return,比如SPFA某个点入队了100次就坚信这个图有负环……

总之,这个技巧使用乱搞恰当的话,可以让你本来就能AC的点继续AC,TLE的点多AC几个点

技巧原理:宁愿WA也不愿意TLE

例:

有一次一道最短路有负权还卡SPFA,加了SLF还超时,全班统一做法:某个点进队200次直接判负环,inline + register,deque换成手写队列

就AC了……

各种玄学的比较

效果方面

1、卡时优化

2、去指针优化

3、去STL优化

4、数组开小优化

5、读入优化

6、inline,register,define

风险方面

1、卡时优化

2、去STL优化

3、数组开小优化

4、读入优化

5、去指针优化

6、inline,register,define

后三个差不多没有任何风险

{{ vote && vote.total.up }}

共 12 条回复

jsq 蒟蒻

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Herobrine 303

0.0

chen_zhe 沙雕

最优写法是最需要卡常的,像什么O(n ^ 3)的就不用卡了,O(nlogn)和O(n)的题目在NOIP中都需要卡常

chen_zhe 沙雕

比如说,一道并查集或者说tarjan,花在算法的时间比读入时间还少的,如果数据范围一千万,cin & scanf 包阵亡

pikahuan 逗比

不就是节约了那一点时间吗,我就不信最优写法还要来四舍五入来节约下时间!

pikahuan 逗比

切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用 切,在乎这点时间有什么用

chen_zhe 沙雕

chen_zhe沙雕 2020-08-19 11:00:56 你去看某个大佬的文章,里面举了很多他被NOIP卡常的例子

chen_zhe 沙雕

滚动数组只能节省空间,不能节省时间,还会让打印方案变得困难

最近NOIP实况就是没人敢用scan,至少都是getchar

NOIP真的很卡常

nlogn可以来个两百万的数据范围

n^2可以来个五千

不看重常数就直接凉掉

pikahuan 逗比

切,在乎这点时间有什么用?爷用滚动数组就可以解决多重循环的困扰

chen_zhe 沙雕

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FZH FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI FZH AK IOI !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!