打FFT时中发现的卡常技巧
题目:洛谷P1919 A*B Problem 加强版
我的代码完全借鉴boshi,然而他380ms我880ms。。。于是我通过彻底的卡(chao)常(dai)数(ma)成功优化到了380ms,都是改了一些等效写法,所以我决定把我发现的技巧贴出来,说不定以后用得到。。。如果你有什么卡常技巧也请告诉我QwQ
1.加register
这个不必多说了吧,卡常基本操作之一,但是貌似加多了也会慢
2.运算符重载时加上取地址符
本来是这样:
class cp
{
public:
double real,imag;
cp operator+(const cp aa)
{return (cp){real+aa.real,imag+aa.imag};}
cp operator-(const cp aa)
{return (cp){real-aa.real,imag-aa.imag};}
cp operator*(const cp aa)
{return (cp){real*aa.real-imag*aa.imag,real*aa.imag+imag*aa.real};}
};
改成了这样:
class cp
{
public:
double real,imag;
cp operator+(const cp& aa)
{return (cp){real+aa.real,imag+aa.imag};}
cp operator-(const cp& aa)
{return (cp){real-aa.real,imag-aa.imag};}
cp operator*(const cp& aa)
{return (cp){real*aa.real-imag*aa.imag,real*aa.imag+imag*aa.real};}
};
原因未知,但快了不少。
3.不要重载等号
如果你写了这样的函数:
cp& operator=(const cp& aa)
{if(this!=&aa){real=aa.real,imag=aa.imag;}return *this}
除非你用等号干一些特殊的事,否则去掉吧。编译器会自动重载等号,而且绝对要更快。
4.去掉多余的构造函数
一开始我是这么写的:
class cp
{
public:
double real,imag;
cp(double x=0.0,double y=0.0)
{real=x,imag=y;}
cp operator+(const cp aa)const
{return cp(real+aa.real,imag+aa.imag);}
//......
};
//in FFT()
cp wn(cos(pi/i),f*sin(pi/i));
改成了这样后:
class cp
{
public:
double real,imag;
cp operator+(const cp aa)
{return (cp){real+aa.real,imag+aa.imag};}
//......
};
//in FFT()
cp wn=(cp){cos(pi/i),f*sin(pi/i)};
就变快了,看来构造函数耗时还是很大的,尤其是当你要设一组变量的时候。
所以说,C++这玩意真的玄学=。=如果你有别的卡常技巧请务必告诉我QwQ