卡常论
前言
时间复杂度仅供参考,请以实际效率为准。
即使复杂度正确的代码,也应该在极限数据下测试其效率,由data.exe与去掉暴力的check.exe共同完成。
同样,对于两个复杂度相同的算法,由于常数原因,一个跑得过,一个就是会TLE,卡常卡不过,就要换算法,不要总想着CCF的机子跑得快。黄奕涵就在省选被卡常了。
-
将递归改为递推
-
优化输入输出
-
确认复杂度真的没问题,避免忽略
log2,__gcd等内置函数以及快速幂的复杂度 -
范围不要开到理论最大范围,实际是多少就用多少
-
手写STL
-
利用c++内置性质:
inline,循环展开 -
随机打乱顺序
一个例子:TLE#13卡常方法
unordered_map的“进队优化”(林子睿在SCOI2024考场上用这个技巧给T1卡常使他进省队),亲测这样查询会非常快(但还是耐不住unordered_map常数实在太大了)。
auto it=mp.find(col);
if(it==mp.end())continue;
sum+=it->second;
在主要的复杂度部分秉承能减少一次就减少一次的观点:
代码来源:序列
原代码:
DP_G(),DP_F();
cout<<(sum+MOD)%MOD<<" ";
for(int j=1;j<=q;){
DP_G(),DP_F();
...
改后代码:
for(int j=1;j<=q;){
DP_G(),DP_F();
if(j==1)cout<<(sum+MOD)%MOD<<" ";
...
\(80\to 100\)
一定不要用 stack 常数太大
用throw直接跳出递归,例:R201788736
少用double,少取模
memset的限制大小初始化,例:R201999060
memset(vst,0,(U+1)*sizeof vst[0]);

浙公网安备 33010602011771号