时间卡常技巧

以下内容出自: 时间卡常技巧

先放一句话镇场:

我觉得,卡常数的出题人都是xx,这违背了算法竞赛考察思路的初衷 ——LYD

推荐:论OI中各种玄学卡常

我们一般说的复杂度都是O(n)O(n^2)O(nlogn)是一个级别。

但是我们其实每一个步可能计算很多次,然后会乘上一个2*n,3*n,甚至10*n 我们都叫O(n)

这个乘上的数就是常数。
有的时候,你(chu)自(ti)己(ren)的(sang)程(xin)序(bing)可(kuang)能(ka)常(chang)数(shu)太(qwq)大(QAQ)

就需要我们优化常数。

(并没有什么具体的解释和代码)

1.小trick

①I\O优化

快速读入与快速输出。

②STL优化

STL出了名的常数大,尤其map,set。

如果常数危险,能手写就避免。

③少调用函数

④使用define优化?道听途说,不准。

2.循环优化

①循环展开

for(int i=1;i<=n;i+=4)
{
    ++a[i];
    ++a[i+1];
    ++a[i+2];
    ++a[i+3];
}
//处理mod 4剩余部分

②while代替for

应该是有用的。但是大部分时候,for和while的思想也不太一样。不太能直接替换。

③前置++

3.运算优化

①取模优化

可以搭配三目运算符,ret=ret+a>=mod?ret+a-mod:ret+a;

②位运算

4.存储优化:

把循环次数较多的放在后面的维数。把较大的一维放在前面。

因为存储空间是连续的。不断跳一大段也是费时费力的。

矩阵乘法就可以用这个优化。

5.利用系统自带优化

①手动O2,O3,Ofast优化

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")

会CE,但是本地打表可以。

②register

对于大量的for中的i可以变成register

③inline

6.实力卡常数

①zkw线段树

7.用空间优化时间

①如果要对int取模,那么数组可以都用int,运算的时候可以强制转化。

可以省空间省时间。

我们不是为了暴力卡常出奇迹,只是为了让我们的正解能得到应有的分数。——《我们为何而卡常》



以下内容出自:卡常技巧

本方法可以让c语言指令进一步接近汇编指令的执行效率,提高单片机,嵌入式系统的速度和稳定性,

但编程时应采取函数化的编程法——例如使用swap()函数时,必要时加注释。

注:本例涉及一些计算机原理的思想,较为抽象,读者可利用1和2(01和10)等简单的数字进行验证,

并上机实验,以加深印象。

0.位运算心法:(掌握粗体字)

&(与逻辑):有0出0,全1出1;

|(或逻辑):有1出1,全0出1;

~(非逻辑):空即是色,色即是空;

^(异或):相异出1,相同出0;

1. 如果乘上一个2的倍数数值,可以改用左移运算(Left Shift) 加速 300%

x = x * 2;
x = x * 64;
//改为:
x = x << 1; // 2 == 21
x = x << 6; // 64 == 26

2. 如果除上一个 2 的倍数数值,可以改用右移运算加速 350%

x = x / 2;
x = x / 64;
//改为:

x = x >> 1; // 2 == 21
x = x >> 6; // 64 == 26

3. 数值转整数加速 10%

x = int(1.232)
//改为:

x = 1.232 >> 0;

4. 交换两个数值(swap),使用 XOR 可以加速20%

var t:int = a;
a = b;
b = t;
//equals:
a = a^b;
b = a^b;
a = a^b;

5. 正负号转换,可以加入 300%

i = -i;
//改为
i = ~i + 1; // NOT 写法
//或
i = (i ^ -1) + 1; // XOR 写法

6. 取余数,如果除数为 2 的倍数,可利用 AND 运算加速 600%

x = 131 % 4;
//equals:
x = 131 & (4 - 1);

7. 利用 AND 运算检查整数是否为 2 的倍数,可以加速 600%

isEven = (i % 2) == 0;
//equals:
isEven = (i & 1) == 0;

8. 加速 Math.abs 600% 的写法1,写法2 又比写法1加速 20%

//写法1
i = x < 0 ? -x : x;

//写法2

i = (x ^ (x >> 31)) - (x >> 31);

//写法3

i=x^(~(x>>31)+1)+(x>>31);

9. 比较两数值相乘之后是否拥有相同的符号,加速 35%

eqSign = a * b > 0;
//equals:
eqSign = a ^ b > 0;

其它位运算技巧
1. RGB 色彩分离

var 24bitColor:uint = 0xff00cc;
var r:uint = 24bitColor >> 16;
var g:uint = 24bitColor >> 8 & 0xFF;
var b:uint = 24bitColor & 0xFF;

2. RGB 色彩合并

var r:uint = 0xff;
var g:uint = 0x00;
var b:uint = 0xcc;
var 24bitColor:uint = r << 16 | g << 8 | b;



我不会生产代码, 我只是代码的搬运工。。。

原文地址:https://www.cnblogs.com/AK-ls/p/11526813.html

时间: 2024-10-11 07:52:11

时间卡常技巧的相关文章

一些卡常技巧

什么?你说这些东西没用? 那你就大错特错了.WC考过的东西怎么可能没用 开O2之后FFT会比不开快几倍 不开O2:NTT比FFT快 开O2:FFT比NTT快 常数尽量声明成常量 有一道NTT的题,模数声明成变量跑了\(1166\)ms,模数声明成常量跑了不到\(300\)ms //6s const int p=10; int main() { open("orzzjt"); int a; scanf("%d",&a); int i; for(i=1;i<

卡常技巧

一般: 1. 思路清晰,简化流程. 2. 数组访问: 高位数组寻址优化. 访问的内存尽量连续. 3. 少用除法.取模. 4. 重复运算,存入临时变量. 5. 循环展开,刺激 CPU 并行.展开次数过多,性能会下降,因为寄存器不够用. 6. 读入优化,输出优化. 分块: 1. 调整块大小. FFT: 1. 减小循环长度. 2. 两次 FFT ,complex(a[] + b[], a[] - b[]) 自乘. 递归: 1. 改写非递归.例如并查集,例如欧几里得算法,等等. STL: 1. 手写.

CodeForces 327E Axis Walking(状压DP+卡常技巧)

Iahub wants to meet his girlfriend Iahubina. They both live in Ox axis (the horizontal axis). Iahub lives at point 0 and Iahubina at point d. Iahub has n positive integers a1, a2, ..., an. The sum of those numbers is d. Suppose p1, p2, ..., pn is a p

论OI中各种玄学卡常

当你在写程序的时候一般出现过这种无比悲剧的情况: 你讨厌卡常?下面有二则小故事: 作为一个经常出题的人,其实很多时候出题时的画风是这样的:"我有一个绝妙的\(O(nlog^2n)\)的算法,我来出道题吧""咦怎么只能跑 \(5w\) 啊,好咸鱼啊,我要让它能跑 \(10w\),嗯现在 \(10w\) 只要 \(0.3s\) 了,要不努把力跑个 \(20w\) 吧"然后就没有然后了.. 开O2之后FFT会比不开快几倍? 不开\(O2\):\(NTT\)比\(FFT\)

Oracle中ID的自动增加以及获取系统时间的小技巧

引自http://blog.csdn.net/lejuo/article/details/4479065 ID自动增加,就像MS- SQL Server里面创建表格时,给表的主键设置为自动增加一样. 在Oracle里面,通过如下的SQL语句实现:(plsql可以直接在sequence创建) -- Create sequence create sequence MSG_IN_ID_SEQminvalue 1maxvalue 999999999999999999999999999start with

Codeforces 988D Points and Powers of Two 【性质】【卡常】

这道题关键在于想到两个性质,想到就好做了.这还是我做过的第一道卡常题 1.满足题目中条件的子集,其中元素个数不能大于3 2.如果最大子集为3的话,那一定是x-2^i,  k, x+2^i的形式,我们枚举x就好了,然后i的次数是log10^9:如果最大子集是2,那就是x,x+2^i的形式,同样枚举x:如果最大子集是1,输出a[1]就行 整体复杂度是O(n*logn*log10^9) 1 #include<iostream> 2 #include<set> 3 using namesp

bzoj4028 [HEOI2015]公约数数列(分块+卡常?)

被卡常卡到怀疑人生. 思维又难又卡常(可能是我写的太丑了)心态炸了. 最后还是照题解打的.(题解多了一个排序,似乎快了很多) 所以代码就不发了... 原文地址:https://www.cnblogs.com/Xu-daxia/p/9465265.html

卡常模板

卡常模板,必背 1 #pragma GCC optimize(1) 2 #pragma GCC optimize(2) 3 #pragma GCC optimize(3) 4 #include<iostream> 5 #include<cstdio> 6 #include<ctime> 7 #include<cstdlib> 8 #include<cstring> 9 #include<algorithm> 10 #define Ri

[luogu1972][bzoj1878][SDOI2009]HH的项链【莫队+玄学卡常】

题目大意 静态区间查询不同数的个数. 分析 好了,成功被这道题目拉低了AC率... 打了莫队T飞掉了,真的是飞掉了QwQ. 蒟蒻想不出主席树的做法,就换成了莫队... 很多人都不知道莫队是什么... 一句话概括莫队:离线询问分块排序,玄学降低复杂度 那么这道题目就是简单的莫队模板套一下就好了,每一次看看更新的点是不是会对答案造成贡献就可以过掉了. 但是复杂度很明显是\(Q(\sqrt{n}m)\),成功T掉,加上玄学卡常,破罐子破摔了100+终于过掉了. #include <bits/stdc+