OI比赛常数优化
这是一篇玄学文章
一、编译优化
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
预处理开O3优化
比赛时除非遇到常数很大可能会卡的暴力题否则一定不要用!玩火自焚!
二、I/O优化
核心:利用getchar()和putchar()这两个底层函数和位运算加速
输入优化(超逼格写法)
#include<cstdio>
#include<cctype>
using namespace std;
int read()
{
int x=,f=;
char c=getchar();
while(!isdigit(c))
{
f|=c=='-';
c=getchar();
}
while(isdigit(c))
{
x=(x<<)+(x<<)+(c^);
c=getchar();
}
return f?-x:x;
}
输入优化
这里为什么可以用c^48代替c-48('0')呢?因为48的二进制是110000,后4位均为0,48~57('9')近在后四位后变化,所以^48可以用来代替-48且更快
听说用fread更快但只能写文件,这里就不写代码了,通常比赛时使用上面的优化即可,有兴趣的读者可以查阅资料了解一下
输出优化
每次使用putchar()输出字符可加速输出
实测递归+putchar()输出整数的速度比printf()快6倍!
但不要写递归版……递归版的速度还慢于printf
放上代码
#include<cstdio>
#include<cctype>
using namespace std;
#define re register int
int stk[],tt;
void print(int x)
{
if(x==)
putchar('');
else
{
if(x<)
putchar('-'),x=-x;
tt=;
while(x)
{
stk[++tt]=x%;
x/=;
}
for(re i=tt;i;i--)
putchar(stk[i]|);
}
}
输出优化
格式控制直接手打putchar()即可
stack[i]|48的正确性由输入优化的解释和或运算的定义显然可知
三、寄存器变量
需要大量运算的变量申请为寄存器变量,即register+类型名
通常将循环变量设为寄存器变量
另外将register int设为字符串常量可以简化代码,详见下面代码
#define re register int
int main()
{
for(re i=;i<=;i++)
return ;
}
申请寄存器变量
不要滥用register,一方面少量变量修改优化效果不明显,另一方面寄存器放不下变量时就会自动把变量放到内存里……
四、取模优化
适用于只有加减运算的题目
int inc(int x,int v,int mod){x+=v;return x>=mod?x-mod:x;}//代替取模+
int dec(int x,int v,int mod){x-=v;return x<?x+mod:x;}//代替取模-
取模优化
五、memset,memcpy以及memmove
memset(数组名+第一个操作数下标,0/-1,操作大小*类型所占字节数)
memcpy(目标数组名+该数组第一个操作数下标,被copy数组名+该数组第一个操作数下标,操作大小*类型所占字节数)
memmove(目标数组名+该数组第一个操作数下标,被清空数组名+该数组第一个操作数下标,操作大小*类型所占字节数)
实例:
//int是4个字节所以用<<2
memset(a+l,,r-l+<<);
memcpy(a+l,b+l,r-l+<<);
memmove(a+l,b+l,r-l+<<);
memset,memcpy和remmove实例
获取类型所占字节数方法:sizeof(类型名)
六、正常的优化
思路:减少运算及比较次数&用位运算代替四则运算
七、程序框架
将register int和long long缩写可以节省时间……用define就行
另外多设一个INF
#include<cstdio>
#include<cctype>
using namespace std;
#define re register int
#define ll long long
const int INF=0x3f3f3f3f;
int stk[],tt;
void print(int x)
{
if(x==)
putchar('');
else
{
if(x<)
putchar('-'),x=-x;
tt=;
while(x)
{
stk[++tt]=x%;
x/=;
}
for(re i=tt;i;i--)
putchar(stk[i]|);
}
}
int read()
{
int x=,f=;
char c=getchar();
while(!isdigit(c))
{
f|=c=='-';
c=getchar();
}
while(isdigit(c))
{
x=(x<<)+(x<<)+(c^);
c=getchar();
}
return f?-x:x;
}
int main()
{
return ;
}
程序框架
结束语
此篇文章介绍的优化均已实测证明,下面是一些误传:
- 迷信inline?实测inline还要稍微慢上一丢丢……
- 前置++和后置++实测在单独语句时没有任何差别
- 用三目运算符(?:)代替if()else()?然而实测三目运算符比if()else()还要慢一些……
OI比赛常数优化的更多相关文章
- OI常用的常数优化小技巧
注意:本文所介绍的优化并不是算法上的优化,那个就非常复杂了,不同题目有不同的优化.笔者要说的只是一些实用的常数优化小技巧,很简单,虽然效果可能不那么明显,但在对时间复杂度要求十分苛刻的时候,这些小的优 ...
- spoj 4487. Can you answer these queries VI (gss6) splay 常数优化
4487. Can you answer these queries VI Problem code: GSS6 Given a sequence A of N (N <= 100000) in ...
- 【DSA MOOC】起泡排序的原理及常数优化
根据学堂在线TsinghuaX: 30240184X 数据结构(2015秋)这门课的内容,对bubblesort做了一些总结. 1. bubblesort(起泡排序),原理来自这样一个观察规律:若序列 ...
- FFT常数优化(共轭优化)
最近闲着无聊研究了下\(FFT\)的常数优化,大概就是各种\(3\)次变\(2or1.5\)次之类的,不过没见过啥题卡这个的吧. 关于\(FFT\)可以看这里:浅谈FFT&NTT. 关于复数 ...
- 【分块】【常数优化】【Orz faebdc】洛谷 P1083 NOIP2012提高组 借教室
分块90分. By AutSky_JadeK [重点在下面] #include<cstdio> #include<cmath> using namespace std; #de ...
- 关于OI中简单的常数优化
有些东西借鉴了这里qwq 1.IO(istream/ostream) 输入输出优化 之后能,在赛场上常见的几种输入输出: 输入: $1.cin$ 呵呵,不说什么了,慢的要死.大概$1e8$个数要读1分 ...
- 一些技巧 && 常数优化 && 出现の错误
开坑原因 7.21 今天DTZ大爷教了我一个算欧拉函数的好方法......是质因数复杂度的 这让我想到,这些小技巧小idea,很多时候,可能就是考场上最致命.最一击必杀的"大招" ...
- bzoj 3240: [Noi2013]矩阵游戏 矩阵乘法+十进制快速幂+常数优化
3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 613 Solved: 256[Submit][Status] ...
- OI中卡常数技巧
一.I/O优化 读入优化是卡常数最重要的一条! inline int read() { ,f=;char c=getchar(); ;c=getchar();} +c-';c=getchar();} ...
随机推荐
- Java中class的声明
在Java中下面Class的声明哪些是错误的?(A,B,C) A:public abstract final class Test { abstract void method();} B:pub ...
- 歌手详情数据处理和Song类的封装
我们现在每首歌曲的数据都是这样的 我们需要在这个数据里面去提取我们需要的部分,来构造成我们需要的数据对象 那我们要和创建singer.js一样 同样也要创建song.js类 我们还要获取到每首歌对应 ...
- Delphi XE2 之 FireMonkey 入门(45Finally) - 结题与问题
Delphi XE2 之 FireMonkey 入门(45Finally) - 结题与问题 很喜欢 FMX 的一些新控件, 如: TExpander.TArcDial.TComboTrackBar.T ...
- HTML学习之==>JS
HTML中的三把利器的JS 又称为JavaScript,看着好像和Java有点联系,实际上他和java半毛钱关系都没有,JavaScript和我们学习的Python.Go.Java.C++等,都是一种 ...
- MSSQL注入--反弹注入
明明是sql注入的点,却无法进行注入,注射工具拆解的速度异常的缓慢,错误提示信息关闭,无法返回注入的结果,这个时候你便可以尝试使用反弹注入, 反弹注入需要依赖于函数opendatasource的支持, ...
- 【Python基础】_1 Python简介
1 Python简介 Python是一种计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项 ...
- maven 异常 提示 cannot be read or is not a valid ZIP file
Archive for required library: 'D:/repository/Maven/org/springframework/spring-aop/4.3.6.RELEASE/spri ...
- linux应用程序启动时加载库错误问题
ldd text查看依赖库 ln -s /lib64/libpcre.so.0 /usr/local/lib/libpcre.so做软连接
- [Python3] 002 Python3 中常用的命名规则
目录 1. 什么可以用来命名? 1.1 老三样: 字母.数字.下划线 1.2 其他 2. 什么不能用来命名? Python3 中的"关键字" 3. 命名"小贴士" ...
- 洛谷 P1541 乌龟棋 & [NOIP2010提高组](dp)
传送门 解题思路 一道裸的dp. 用dp[i][j][k][kk]表示用i个1步,j个2步,k个3步,kk个4步所获得的最大价值,然后状态转移方程就要分情况讨论了(详见代码) 然后就是一开始统计一下几 ...