整理的算法模板合集: ACM模板
取模优化:
inline int inc(int x,int v,int mod){x+=v;return x>=mod?x-mod:x;}//代替取模+
inline int dec(int x,int v,int mod){x-=v;return x<0?x+mod:x;}//代替取模-
或者对于模数p进行#define宏定义
绝对值优化:
inline int Abs(int a){//绝对值优化
{
int b=a>>31;
return (a+b)^b;
}
NO.9:前置++/--
运算符:(有利无弊)
NO.8: if()else
语句比()?():()
语句慢(但慢的不多,在判断较少的时候还是用if吧)。
网上很多说if比?:慢,但是其实不是这样的。二者的汇编除了文件名不一样其他都一模一样。其实不是?:比if快而是?:比if-else快。
函数内联:比如说:
inline add(int u,int v)
{
star[++cnt].to=v;
star[cnt].nxt=head[u];
head[u]=cnt;
}
但要拒绝inline
大递归函数,用的少的函数比如只用1
次的就不要inline
了,那样反而更慢;
另类内联:
struct haha{
int v,x;
inline bool operator < (haha tar){//强制内联
return v<tar.v;
}
}lala[MAXN+1];
因为局部变量是存在于堆栈中的,对其空间的分配仅仅是修改一次esp
寄存器的内容即可.而局部变量存在于堆栈中最大的好处是,函数能重复使用内存,当一个函数调用完毕时,退出程序堆栈,内存空间被回收,当新的函数被调用时,局部变量又可以重新使用相同的地址。当一块数据被反复读写,其数据会留在CPU
的一级缓存(Cache
)中,访问速度非常快。而静态变量却不存在于堆栈中。
STL
大部分的STL较慢的原因是在动态内存分配时对push_back()
的函数大大的不友好;
我们可以手写足够大小的内存池来代替动态分配内存。
#include
using namespace std;
#define reg register
static char space[10000000],*sp=space;
template<typename T>
struct myalloc:allocator<T>{
myalloc(){}
template<typename T2>
myalloc(const myalloc<T2> &a){}
template<typename T2>
myalloc<T>& operator=(const myalloc<T2> &a){return *this;}
template<typename T2>
struct rebind{typedef myalloc<T2> other;};
inline T* allocate(size_t n){
T *result=(T*)sp;sp+=n*sizeof(T);
return result;
}
inline void deallocate(T* p,size_t n){}
};
list<int,myalloc<int> > L;vector<double,myalloc<double> > vec //容量的定义
但当内存过大时,不要套用此代码,因为该代码为了简短并没有释放内存;
scanf
比cin
快得多,printf
比cout
快得多,如果你不知道就……就现在知道了
普通版:(适用于正负int
范围内的数)
void read(int &x)
{
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
提升版:(快是快,但在考试中的性价比并不高)
inline char get_char(){//超级快读
static char buf[1000001],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
int num=0;
char c;
while(isspace(c=get_char()));
while(num=num*10+c-48,isdigit(c=get_char()));
return num;
}
register
在定义一个变量时加一个register
,其意义是将该变量放入寄存器中进行运算(如果可以的话),
它的效果在该变量不断重复使用时间的优化极大,往往用时是不优化的40%
;
#pragma GCC optimize(2)
(请勿在NOIP中作死)这便是O2优化
它的作用极大,但如果代码不规范,它在优化时会改变某句代码的含义,所以在用时一定要小心从30%TLE变为100%WA
;
clock()
大法好!clock()函数可以返回当前的运行时间,也就是说在进行循环或者爆搜的时候超时,时间限制为 1 s 1s 1s 我们就可以判断一下当前是否超时,如果快要超时了就立刻break
出来,避免TLE
具体用法如下:
#include
#include
#include
#include
using namespace std;
int start = clock();
int main(){
cout<<CLOCKS_PER_SEC<<endl;
for(int i = 0; ; ++i){
if(i % 100000 == 0 && clock() - start >= CLOCKS_PER_SEC * 0.9){
cout<<i<<endl;
cout<<clock() - start <<endl;
exit(0);
}
}
return 0;
}
输出:
需要注意两点:
i % 100000000 == 0
1000000
为1s,而windows中经过测试为1000
为1s然后玩这个可以测试你的电脑的性能