常卡,乃诺骗分最重要的秘诀,这里总结了常卡常(来自一些大牛的博客)
持续更新中
目录
正文
一、位置
1.如果上一个2的倍数,可以改用左移(Left Shift)加速300%
x = x * 2;
x = x * 64;
改为:
x = x << 1;
x = x << 6;
2. 如果除上一个 2 倍数的成绩,可以改用右移加速运动 350%
x = x / 2;
x = x / 64;
改为:
x = x >> 1;
x = x >> 6;
3. 会员转加速 10%
x = int(1.232)
改为:
x = 1.232 >> 0;
4.交换两个(swap),使用XOR可以加速20%
int a,b,c;
c = b;
b = a;
a = c;
改为:
a = a ^ b;
b = a ^ b;
a = a ^ b;
5. 正负号转换,可以加入300%
·cpp a = -a; ···改为:
i = ~i + 1; // NOT 写法
i = (i ^ -1) + 1; // XOR 写法
6. 取余数,如果数为 2 的倍数,可利用并加速除数 600%
x=131%4;
x=x&(4-1);
7. 使用 AND 考试是否必须为 2 的倍数,可以加速 600%
if(1%2==0)
if(i&1==0)
8. 加速加速 Math.abs 600% 的写法1,写法2 又比写法1 20%
//写法1
i = x < 0 ? -x : x;
//写法2
i = (x ^ (x >> 31)) - (x >> 31);
//或者
i=x^(~(x>>31)+1)+(x>>31);
9.x++ 可以用位解决
x++;
改为:
x=-~x;
10.求2的n次方(当然快速提升)
x=pow(2,y);
x=1<<y;
二、循环
1.i++与++i,++i来,一下是c++源码
++i
INT INT::operator++()
{
*this=*this+1;
return *this;
}
const INT INT::operator ++(int)
{
INT oldvalue=*this;
*this=*this+1;
return oldvalue
}
所以,审核
for ( int i=1;i<=n;i++){
}
|
改为:
for ( int i=1;i<=n;++i){
}
|
2.把循环给展开试,速度会快很多
情况1(循环执行多条语句):
1
2
|
for ( int i=1;i<=n;++i)
a=1,b=1;
|
改为:
1
2
|
for ( int i=1;i<=n;++i)a=1;
for ( int i=1;i<=n;++i)b=1;
|
情况2(循环执行单条语句):
1
2
3
4
5
6
7
8
9
|
double sum( double *a, int n)
{
double s=0;
for ( int i=1;i<=n;i++)
{
s+=a[i];
}
return s;
}
|
改为:
1
2
3
4
5
6
7
8
9
10
11
12
|
double sum( double *a, int n)
{
double s0=0,s1=0,s2=0,s3=0;
for ( int i=1;i<=n;i+=4)
{
s0+=a[i];
s1+=a[i+1];
s2+=a[i+2];
s3+=a[i+3];
}
return s0+s1+s2+s3;
}
|
3.++i 原则上可以更优化(使用位自由)
1
2
3
|
for ( int i=1;i<=n;++i)
{
}
|
改为:
1
2
3
|
for ( int i=1;i<=n;i=-~i)
{
}
|
4. 5. 在循环中广泛进行的同时,要提高循环效率,从编入代码可以高度理解,在高度理解6. 6. 33. 节前,可以在节时,将节前,将,while转换为do...while
1
2
3
4
|
for (;;){
}
while (){
}
|
改为:
1
2
|
do {
} while ()
|
if() else语句比()?():()语句要慢
1
2
|
if ()
else
|
改为:
1
|
()?():()
|
三、属性与变量
1.在int前加寄存器
1
|
int a;
|
改为:
1
|
register int a;
|
2. 异常语句
1
|
int a=1;
|
改为:
1
|
int a(1);
|
3.能不用变量就不用,转而用特征
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//10s
int p=10;
int main()
{
open( "orzzjt" );
int a;
scanf ( "%d" ,&a);
int i;
for (i=1;i<=1000000000;i++)
a=(a*a+10)%p;
printf ( "%d\n" ,a);
return 0;
}
|
改为:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//6s
const int p=10;
int main()
{
open( "orzzjt" );
int a;
scanf ( "%d" ,&a);
int i;
for (i=1;i<=1000000000;i++)
a=(a*a+10)%p;
printf ( "%d\n" ,a);
return 0;
}
|
4.多维菜请把大的放前面
1
|
int dp[2][10][100000];
|
改为:
1
|
int dp[100000][10][2];
|
5.speed bool慢于char慢于int
所以在不考虑空间的情况下,尽量使用int而不是bool
1
|
bool a[10000];
|
改为:
1
|
int a[10000];
|
四.函数
1.在函数前加inline可以魔梯
1
2
3
4
|
int x( int a, int b)
{
return a+b;
}
|
改为:
1
2
3
4
|
inline int x( int a, int b)
{
return a+b;
}
|
五、输入输出
1.读入优化
1
|
scanf ( "%d" ,&a);
|
改为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
inline int read()
{
int x,f=1;
char ch= getchar ();
while (ch< '0' ||ch> '9' )
{
if (ch== '-' )
{
f=-1;
}
ch= getchar ();
}
while (ch>= '0' &&ch<= '9' )
{
x=(x<<3)+(x<<1)+ch- '0' ;
ch= getchar ();
}
return x*f;
}
|
2.字符串输入输出能用char就别用string
1
2
3
|
string s;
cin>>s;
cout<<s;
|
改为:
1
2
3
|
char c[100];
scanf ( "%s" ,c);
printf ( "%s" ,c);
|
3.和输入一样,输出也有快写
1
|
printf ( "%d" ,x);
|
改为:
1
2
3
4
5
6
7
8
9
10
11
|
inline void print( int x)
{
int ot;
while (x)
{
ot=x%10;
putchar (ot+ '0' );
x/=10;
}
return ;
}
|
六、搜索
1.当dfs快速直接定位时,停止搜索,输出当前最优解
模板:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include<ctime>
#include<cstdlib>
#include<iostream>
using namespace std;
double t;
const double CLOCKS_PER_SECOND=(( clock_t )1000); //定义常量
void dfs()
{
cout<<1;
if (1000*( clock ()-t)>=900*CLOCKS_PER_SECOND) //即将超过1000ms时输出答案并结束程序,防止超时
{
/*输出答案*/
exit (0); //退出
} else
dfs(); //否则继续搜索
}
int main(){
t= clock (); //记录开始时间
dfs();
return 0;
}
|
七、习题
1.取模
1
2
3
|
int mod( int x, int y){
return x%y;
}
|
改为:
1
2
3
|
int mod( int x, int y){
return x - y * (x / y);
}
|
然而可以做到:
1
2
3
|
int mod( int x, int y){
x=x&(1<<y-1);
}
|
2.加法取模
1
|
ll add(ll a,ll b){ return (a+b)%p;}
|
改为:
1
|
ll add(ll a,ll b){a+=b; return (a>=b?a-=p:0),a;}
|
减法同理
3地址还是重载时(不知道是c++)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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));
|
改为:
1
2
3
4
5
6
7
8
9
10
11
|
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)};
|