关于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) ...
随机推荐
- 【335】Install PyDev in Eclipse IDE
Reference: Eclipse和PyDev搭建完美Python开发环境(Windows篇) Reference: Install the PyDev plug-in for Eclipse Do ...
- Linux内存地址映射
引言 看过原博主的一些文章,写得很好,虽然博主不提倡这种拿来主义,但我还是忍不住一时手痒.呵呵本文是针对32位x86 CPU中Linux内核地址映射过程的详细介绍和示例.其中由浅入深,介绍了相关寄存器 ...
- 2017面向对象程序设计(Java)第六周学习总结
转眼间,2017年的法定节日已经休完,我们的java学习也已经进行了六周.下面,我将对上个礼拜的学习情况进行总结. 首先,是学习态度问题.虽然同学们已经从家或者各个旅游景点回来,但是心还是没回来.有同 ...
- pg_hba.conf、pool_hba.conf 以及 pool_passwd 三者间的关系
pg_hba.conf.pool_hba.conf 以及 pool_passwd 三者间的关系: 1.pg_hba.conf.pool_hba.conf 以及 pool_passwd 三者关系 pg_ ...
- 尝试编写的rabbitmq+spring 框架
spring有自己的一套框架与消息队列结合使用http://projects.spring.io/spring-amqp/,这个接下来会好好的研究一下. 在领导的帮助下,终于勉强写完了这个消息队列的框 ...
- [分享]PY的Boost自动编译程序 1.1 根据环境自动编译
Python写的Boost自动编译程序 1.1 改进: 根据自己的环境筛选出已安装环境,并列出 环境提供选择. 支持X64位的自动参数编译. 可以选择编译的参数,其他版本持续改进中 自动编译自动安装到 ...
- MySQL性能调优与架构设计——第9章 MySQL数据库Schema设计的性能优化
第9章 MySQL数据库Schema设计的性能优化 前言: 很多人都认为性能是在通过编写代码(程序代码或者是数据库代码)的过程中优化出来的,其实这是一个非常大的误区.真正影响性能最大的部分是在设计中就 ...
- .NET基础 (11)类型的基类System.Object
类型的基类System.Object1 是否存在不继承自System.Object类型的类2 在System.Object中定义的三个比较方法有何异同3 如何重写GetHashCode方法 类型的基类 ...
- Hdu1051 Wooden Sticks 2017-03-11 23:30 62人阅读 评论(0) 收藏
Wooden Sticks Problem Description There is a pile of n wooden sticks. The length and weight of each ...
- java并发编程实战:第十六章----Java内存模型
一.什么是内存模型,为什么要使用它 如果缺少同步,那么将会有许多因素使得线程无法立即甚至永远看到一个线程的操作结果 编译器把变量保存在本地寄存器而不是内存中 编译器中生成的指令顺序,可以与源代码中的顺 ...