关于OI中简单的常数优化
1.IO(istream/ostream) 输入输出优化
之后能,在赛场上常见的几种输入输出:
输入:
$1.cin$ 呵呵,不说什么了,慢的要死。大概$1e8$个数要读1分钟左右
$2.scanf, \_ \_ builtin \_ scanf()$ $scanf$ 其实还不算太快,但是$\_ \_ builtin \_ $在$NOIp$赛场上会$CE$
$3.read()$ 美其名曰:读入优化(反正本宝宝不会),在各大神犇的提交记录以及题解上随处可见,亲测确实比$scanf$要快许多
代码大概长这样: $by\ Young\ Neal$
int getint(){
int x=,f=;char ch=getchar();
while(!isdigit(ch)) f|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<)+(x<<)+(ch^),ch=getchar();
return f?-x:x;
}
$4. fread$ 欢迎来自$AK$爷的飞速文件读入输出
struct file_io{
#define isdigit(ch) ((ch) >= '0' && (ch) <= '9')
char inbuf[ << ], *pin, outbuf[ << ], *pout;
int stk[]; file_io(): pout(outbuf) {fread(pin = inbuf, , << , stdin);}
~file_io() {fwrite(outbuf, , pout - outbuf, stdout);} inline void getint(int &num){
bool neg = ; num = ;
while(!isdigit(*pin)) if(*pin++ == '-') neg = ;
while(isdigit(*pin)) num = num * + *pin++ - '';
if(neg) num = -num;
} inline void putint(int num){
static int *v = stk;
if(!num) *pout++ = '';
else{
if(num < ) *pout++ = '-', num = -num;
for(; num; num /= ) *v++ = num % ;
while(v != stk) *pout++ = *--v + '';
}
} inline void nextline() {*pout++ = '\n';}
} fio;
#define getint(num) fio.getint(num)
#define putint(num) fio.putint(num)
#define nextline() fio.nextline()
输出:
$1.cout$ 呵呵,和$cin$一个样
$2.printf , \_ \_ builtin \_ printf$ 已经比上面那个快多了,但是一样,$\_ \_ builtin \_ printf$会$CE$
$3.puts("")$ 对于已知字符串来说,能用 $puts()$不用$printf()$ 但是$puts("")$输出之后会换行
$4.fio$见上面 (STO GhostCai)
当然了,在$NOIp$范畴内,输入输出量并不算太大,多数$printf(),scanf()$就可以了,
除非$……$
你是要暴力碾标算然后再去$diss$一顿出题人数据水的神犇$……$
这时候读优就必不可少了。
2.内存优化
某$shadowice1984$大佬最擅长的东东,以下引用$shadowice1984$给本宝宝讲课时候的话:
“我们的$CPU$要对某一个数进行计算的时候,会先在一级缓存中找这个数的地址要是找到了,直接揪过来~~枪毙~~进行计算,速度很快的,
但是一级缓存能储存的东西很少,就是几个$int$,如果没有找到,成为'一级缓存未命中',但是,这时候,我们还有一个二级缓存和三级缓存,同样,也很很快,
而‘三级缓存未命中’之后,却要去内存里找这个东西了,这里面会经历虚拟地址与物理地址的互相转换然后还有$……(\text{此处省略})$然后耗时巨大(相对于从缓存直接调用来讲)。
这是后,我们就会称为$cache\ miss$,而如果我们的程序因为$cache\ miss$的次数太多而导致常数因子看似特别大(理论复杂度正确但是就是$tle$),就习惯的成为卡$cache$”
当本宝宝听完这段话之后,
哇$……$真是一个暴力碾标算的好方法
那么$……$我们怎么才能减少$cache\ miss$呢?
$1.$保证内存的连续访问
这就是为什么本宝宝邻接链表写的每次都比别人慢上差不多一倍$qwq$ ,因为现在只有本宝宝用结构体写了啊啊啊啊啊啊!
$2.$多个$for$循环可以适当调整顺序
最明显的就是矩阵乘法和$Folyd$算法了,对于$folyd$ $(eg. \ NOIp2016 \text{换教室})$
for(int i=;i<=n;i++)
for(int j=;j<i;j++)
for(int k=;k<=n;k++)
d[i][j]= d[j][i]=min(d[i][j],d[i][k]+d[k][j]);
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<i;j++)
d[i][j]=d[j][i]=min(d[i][j],d[i][k]+d[k][j]);
亲测第二种写法会比第一种写法快好多呢。
矩阵乘法同理,
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
c.num[i][j]+=a.num[i][k]*b.num[k][j];
把$k$这一维放到外面明显比放到里面要快
3.register 与 inline
$register$在$for$里面真的会快一点,用法就是$for(register int i=1;i<=n;i++)$
$inline$ 只能用在没有递归的函数里,其实手动$inline$是个很好的东西,但是不一定。
这两个有的时候会造成负优化,这就呵呵了。
4.(仅限于$NOIp$等不开$O2$的赛事上) 手写$stl$
$stl(\ C++ \ Standard\ Template \ Library \ )$ 确实特别好用,也是$C++$的精华所在,
可以为程序员们节省很大的时间,
但是,在不开$O2$的情况下,会因为种种原因慢的要死,
尽量背过一些简单的数据结构,能少用就少用。
5.玄学(信仰)优化:
(1). 打表优化
如果有的写的非正解,但是又想拿高分,全打表得话会超过代码长度限制,这是后可以部分打表,记得做过一道题
对于30%的数据,满足n<=500;
对于100%的数据,满足n<=1000;
然后我和$shadowice1984$都会一个$On^{3}$的方法,显然肯定过不了$1000$
之后,本宝宝放弃了,拿了$30$分去一边哭去了,
$shadowice1984$,$n^{3}$信仰过$500$,然后又信仰的打了一下$n=995$到$n=1000$的表
然后就$……$ 然后就 $A$ 了
数据范围内,只打极限数据,放心,出题人一定会很毒瘤的
还有优化打表的方法:查分优化,二次查分优化,$26$进制压缩($eg.$树的平均路长问题)
(2).女装优化(亲测有效)
女装可以大大的减少$bug$和常数,真的亲测有效,模拟赛的时候$t$的东西,**后再测就过了。。
(3).神犇优化(亲身经历)
有一次网上打$nowcoder$的比赛,然后和旁边的神犇代码比较一下只有变量名不同(才不是互相抄的呢)
然后$……$人家神犇就过了,本宝宝就$T$了,
平时做题的时候,本宝宝经常出现用时和神犇差距很大,
自己写线段树都已经不记录$l,r$了,还比那些开结构体记录$l,r$的神犇慢$……$
真的是人菜常数大,真的是$……$
~~所以想暴力碾标算的话,先要成为神犇~~
(4).信仰优化
$srand(1926****)$ $srand(\text{cp或神犇生日})$
$eg.\ srand(20020902) \ \ srand(20020224) $
(左cp右神犇)
然后当你
printf("%s",rand()%?"Yes":"No")
的时候会增大$AC$率的 ($NOIp2017\ \ D1\ \ T2$)
希望有用(光速逃~)
关于OI中简单的常数优化的更多相关文章
- 浅谈OI中的底层优化!
众所周知,OI中其实就是算法竞赛,所以时间复杂度非常重要,一个是否优秀的算法或许就决定了人生,而在大多数情况下,我们想出的算法或许并不那么尽如人意,所以这时候就需要一中神奇的的东西,就是底层优化: 其 ...
- OI常用的常数优化小技巧
注意:本文所介绍的优化并不是算法上的优化,那个就非常复杂了,不同题目有不同的优化.笔者要说的只是一些实用的常数优化小技巧,很简单,虽然效果可能不那么明显,但在对时间复杂度要求十分苛刻的时候,这些小的优 ...
- input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has
input屏蔽历史记录 设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处 ;(function($){$.ex ...
- [技术]浅谈OI中矩阵快速幂的用法
前言 矩阵是高等代数学中的常见工具,也常见于统计分析等应用数学学科中,矩阵的运算是数值分析领域的重要问题. 基本介绍 (该部分为入门向,非入门选手可以跳过) 由 m行n列元素排列成的矩形阵列.矩阵里的 ...
- GCC&&GDB在OI中的介绍
序言 这本来是用Word写的,但是后来我换了系统所以只能用markdown迁移然后写了...... $\qquad$本文主要投食给那些在Windows下活了很久然后考试时发现需要用命令行来操作时困惑万 ...
- OI中的莫比乌斯反演
OI中的莫比乌斯反演 莫比乌斯函数 想要学习莫比乌斯反演,首先要学习莫比乌斯函数. 定义 莫比乌斯函数用\(\mu(x)\)表示.如果\(x\)是\(k\)个不同质数的积,则\(\mu(x) = (- ...
- 在 Prim 算法中使用 pb_ds 堆优化
在 Prim 算法中使用 pb_ds 堆优化 Prim 算法用于求最小生成树(Minimum Spanning Tree,简称 MST),其本质是一种贪心的加点法.对于一个各点相互连通的无向图而言,P ...
- 浅谈分治算法在OI中的应用
分治虽然是基本思想,但是OI中不会出裸分治让你一眼看出来,往往都是结合到找规律里面. 先来个简单的: 奇妙变换 (magic.pas/c/cpp) [问题描述] 为了奖励牛牛同学帮妈妈解决了大写中 ...
- JS代码的简单重构与优化
JS代码的简单重构与优化(适合新手) 原文 http://www.cnblogs.com/similar/p/5016424.html Demo . 1 //bad if (age > 20) ...
随机推荐
- Direcshow相关资料
CCapture directshow 视频捕获类: http://blog.csdn.net/xgx198831/article/details/7284618 ICaptureGraphBuild ...
- 实现JNI的另一种方法:使用RegisterNatives方法传递和使用Java自定义类 (转)
原帖地址:http://blog.csdn.net/qiuxiaolong007/article/details/7860610 除了使用传统方法实现JNI外,也可以使用RegisterNatives ...
- sql中纵表变横表
纵表格式如图所示: 查询sql语句如下: ),content)content,Date from SummerChina ' 变成横表如图所示: 纵表变横表sql语句如下: select Time, ...
- 怎么查看在centos中创建的用户组
用户列表文件:/etc/passwd 用户组列表文件:/etc/group 查看系统中有哪些用户:cut -d : -f 1 /etc/passwd 查看可以登录系统的用户:cat /etc/pass ...
- 在spring中使用quartz配置作业的二种方式
- lda spark 代码官方文档
http://spark.apache.org/docs/1.6.1/mllib-clustering.html#latent-dirichlet-allocation-lda http://spar ...
- ios7 导航栏适配
ios ui开发过程中,经常会使用到导航栏,默认的样式比较单一,所以经常需要修改导航栏的样式 ios4: - (void)drawRect:(CGRect)rect { UIImage *image ...
- 优化 resolv.conf
DNS lookup 在把域名解析成 IP 过程中耽误了不少时间,尤其是访问比较复杂的网站的时候,比如某个页面包含多个 url,一次请求需要做多次 DNS 解析,并且从用户浏览器到 DNS serve ...
- 多因子降维法(MDR,Multifactor Dimensionality Reduction )
多因子降维法(MDR,multifactor dimensionality reduction) 多因子降维法(MDR,Multifactor Dimensionality Reduction ) ...
- HTML5 本地存储+layer弹层组件制作记事本
什么是 HTML5 Web 存储? 使用HTML5可以在本地存储用户的浏览数据. 早些时候,本地存储使用的是 cookie.但是Web 存储需要更加的安全与快速. 这些数据不会被保存在服务器上,但是这 ...