OI一些奇怪的优化手段和常用技巧
2017-10-25 08:39
405 查看
经典的O3优化(一般写在开头)
G++手动扩大栈(写在main的开始)
C++手动扩大栈(一般比较少起作用,推荐上面那个)
G++ 64位手动扩大栈
读入优化
更快的读入优化
如果输入文件较大以上方法可以把ch=str[stl++]改成自己实现的getchar,具体代码如下
线段树和树状数组记得使用位运算
ST表
不要用math库的log!自己预处理!
对于s[i][j]=f(s[i][j-1],s[i+(1<<j-1)][j-1]),我们将i,j的顺序调换一下可以提高效率
特别是在二维ST表效果显著,速度提升四倍有多
取模
首先不得不说把模数写成变量是不太好的做法。。。
我们可以
如果题目要求输入模数呢?
我们还是可以
如果只有加法,我们考虑判定性取模即可
空间优化,记得C++有一个不常用的东西:short
在64位机器上少用指针因为它和long long一样费空间
对于一些奇怪的64位的OJ,我们可以使用__int128来过一些毒瘤数论题(比如对10^18取模)
关于memset和memcpy以及memmove
这几个函数效率都非常高,比循环的速度快很多
其实用法也很简单,比如原code是这样的
注意,左移的位数和a,b的类型有关,这里默认为int,sizeof(int)=4,所以就是左移2(乘4)
如果不知道a,b类型所占字节数,可以改成如下
关于Dijkstra算法
一般的教材(误)上面都说:只适用于所有边权为正的情况
而实际上,dijk+heap是可以在负权图上面跑的,而且比spfa还好写
具体实现,去掉vis数组就好了,虽然这样效率可能比不上spfa了(因为有一个log)
关于负权回路和spfa
如果题目就是要你找一个负环,我们可以直接将queue<int>改成priority_queue<int>
这样通常效率会提高很多(仅限于找负环,跑一般的最短路会慢)
如果还想更快,就把priority_queue<int> 的比较函数变成以下的函数(自己实现一个类似greater<int>的东西)dist是距离
zkw线段树:常数优化神器
如果对于值域不大的数据维护类似平衡树的操作,推荐用这个代替,常数小得可以和并查集比快(虽然复杂度不可比)
当然如果对于值域比较大的数据还是老老实实用递归式权值线段树吧
待更新。。。
如果有人有任何想法欢迎在下面评论,补充一些这里没有的技巧也是资磁的
#pragma GCC optimize("O3") #pragma G++ optimize("O3")
G++手动扩大栈(写在main的开始)
int size = 256 << 20; // 256MB char *p = (char*)malloc(size) + size; __asm__("movl %0, %%esp\n" :: "r"(p));
C++手动扩大栈(一般比较少起作用,推荐上面那个)
#pragma comment(linker, "/STACK:102400000,102400000")
G++ 64位手动扩大栈
extern int main2(void) __asm__ ("main2"); int main2(){ exit(0); }//在这里写main函数 int main(){ int size=64<<20; char *p=(char*)malloc(size)+size; __asm__ __volatile__("movq %0, %%rsp\n" "pushq $exit\n" "jmp main2\n" :: "r"(p)); }
读入优化
inline int rd(int& X){ char ch=X=0; for(;ch<'0' || ch>'9';ch=getchar()); for(;ch>='0'&&ch<='9';ch=getchar()) X=(X<<3)+(X<<1)+ch-'0'; return X; }
更快的读入优化
char str[10000001]; int stl=0; inline int rd(int& X){ char ch=X=0; for(;ch<'0' || ch>'9';ch=str[stl++]); for(;ch>='0'&&ch<='9';ch=str[stl++]) X=(X<<3)+(X<<1)+ch-'0'; return X; } int main(){ fread(str,10000000,1,stdin); }
如果输入文件较大以上方法可以把ch=str[stl++]改成自己实现的getchar,具体代码如下
#define SIZE 1000000 char str[SIZE]; int stl=SIZE; inline char getch(){ return stl==SIZE?fread(str,SIZE,1,stdin),str[stl=0]:str[stl++]; } inline int rd(int& X){ char ch=X=0; for(;ch<'0' || ch>'9';ch=getch()); for(;ch>='0'&&ch<='9';ch=getch()) X=(X<<3)+(X<<1)+ch-'0'; return X; }
线段树和树状数组记得使用位运算
ST表
不要用math库的log!自己预处理!
对于s[i][j]=f(s[i][j-1],s[i+(1<<j-1)][j-1]),我们将i,j的顺序调换一下可以提高效率
特别是在二维ST表效果显著,速度提升四倍有多
取模
首先不得不说把模数写成变量是不太好的做法。。。
我们可以
#define M 1000000007 const int M=1000000007
如果题目要求输入模数呢?
我们还是可以
int main(){ int p; scanf("%d",&p); const int Mod=p; }
如果只有加法,我们考虑判定性取模即可
int mod(int x){ return x>Mod?x-Mod:x; }
空间优化,记得C++有一个不常用的东西:short
在64位机器上少用指针因为它和long long一样费空间
对于一些奇怪的64位的OJ,我们可以使用__int128来过一些毒瘤数论题(比如对10^18取模)
关于memset和memcpy以及memmove
这几个函数效率都非常高,比循环的速度快很多
其实用法也很简单,比如原code是这样的
for(int i=l;i<=r;++i) a[i]=0; for(int i=l;i<=r;++i) a[i]=b[i]; for(int i=l;l<=r;++i) a[i]=b[i],b[i]=0;我们可以改成
memset(a+l,0,r-l+1<<2); memcpy(a+l,b+l,r-l+1<<2); memmove(a+l,b+l,r-l+1<<2);
注意,左移的位数和a,b的类型有关,这里默认为int,sizeof(int)=4,所以就是左移2(乘4)
如果不知道a,b类型所占字节数,可以改成如下
memset(a+l,0,(r-l+1)*sizeof(a[0])); memcpy(a+l,b+l,(r-l+1)*sizeof(a[0])); memmove(a+l,b+l,(r-l+1)*sizeof(a[0]));
关于Dijkstra算法
一般的教材(误)上面都说:只适用于所有边权为正的情况
而实际上,dijk+heap是可以在负权图上面跑的,而且比spfa还好写
具体实现,去掉vis数组就好了,虽然这样效率可能比不上spfa了(因为有一个log)
关于负权回路和spfa
如果题目就是要你找一个负环,我们可以直接将queue<int>改成priority_queue<int>
这样通常效率会提高很多(仅限于找负环,跑一般的最短路会慢)
如果还想更快,就把priority_queue<int> 的比较函数变成以下的函数(自己实现一个类似greater<int>的东西)dist是距离
inline bool cmp(int a,int b){ return dist[a]>dist[b]; }
zkw线段树:常数优化神器
如果对于值域不大的数据维护类似平衡树的操作,推荐用这个代替,常数小得可以和并查集比快(虽然复杂度不可比)
当然如果对于值域比较大的数据还是老老实实用递归式权值线段树吧
待更新。。。
如果有人有任何想法欢迎在下面评论,补充一些这里没有的技巧也是资磁的
相关文章推荐
- PHP常用的一些优化技巧
- tomcat的一些常用的优化技巧
- PHP常用的一些优化技巧
- Visio技巧篇之一些常用小技巧
- 深层优化 提高网站的访问速度的一些技巧
- 安装 Windows 8 之后值得你去做的一些优化技巧
- asp.net 开发的一些常用技巧
- 分享yum的一些常用、实用使用技巧
- [Google]google一些常用的搜索技巧探讨
- 一些常用css技巧的为什么(一)我所理解的margin
- 收藏整理的一些Python常用方法和技巧
- Javascript中最常用的一些经典技巧
- 一些小知识小经验(使用java或者c语言实现的socket服务器的优化技巧)
- 【转】.Net技巧:ASP.NET中常用的26个优化性能方法
- 一些常用代码编辑器(Vi、gedit、EditPlus、SourceInsight)的使用技巧小结
- Asp.NET中常用的一些优化性能的方法
- 15个常用JS优化代码技巧
- 平时常用的一些Linux命令技巧
- Swift开发过程中常用到的一些使用技巧和注意的地方
- C语言系列(二):最近重拾C语言的想法,谈到C中易错点,难点;以及开源代码中C语言的一些常用技巧,以及如何利用define、typedef、const等写健壮的C程序