zoukankan      html  css  js  c++  java
  • 卡常相关

    卡常太难了

    链接:论OI中各种玄学卡常

    卡常常识

    为何卡常?什么时候要卡常?

    通常像分块,莫队等等这样的根号算法以及某些常数巨大的算法(如 Splay 等)可能会被卡常。考试的时候非正解算法有时卡常能够拿到更多的分数(尤其是面对数据不是非常大,算法又常常跑不满的时候,可能会 (n^2) 过一万)。

    平时保持卡常的小习惯,不要写那么多冗余代码也是比较重要的,同时对调试有利。

    至于常数因素对程序的速度的影响究竟有多大,可以看这道题:#2989. 「CTSC2016」NOIP十合一
    (的第一个测试点)。平时对于1e9的规模通常认为O(n)是过不去的,但是由于运算只有十亿次普通的加乘模,在本机五六秒就跑完了。

    通常情况下,如果常数足够小,2s可以跑1e9(本机测试不开O2 int ct = 0; while(++ct <= 1e9); 2秒跑完,开O2 40ms 跑完,估计有编译优化)。不过在一般的题的常数下 (1s10^8) 还是可以的。如果是 Splay 的话就不好说了。

    如何卡常?

    • 对着复杂度瓶颈使劲卡,同为复杂度瓶颈的部分要优先对着常数较大的那部分使劲卡。不要一个 (O(n log n)) 的题只对着一个 (O(n)) 的部分卡

    • inline read()

    • 一般情况下递归要比循环慢一些,所以如果被卡常了或许可以用循环代替递归试一试。

    • 当我们确定输入中不存在负数的时候,可以把快读中对负数的特判去掉。

    • 减少冗余计算,尽量优化常数。必要时以空间换时间。

    • 手写 STL 的 (stack, queue, deque)(vector) 也可能会被卡,但是不太好手写,不过还是可以替代的(如用邻接链表)

    • 实在不行尝试深夜提交,或者多次提交碰运气

    • 有时候删掉一些调试遗留下来的语句可以加快一下速度,毕竟虽然能保证不进入“if”,但是每次判断一下会拉慢速度。当然,正式考试的时候千万不要遗留调试语句,否则可能本来可能骗到分的测试点就自动弃权了。

    • 可以尝试把DFS改成BFS,通常会快很多。如果想要多次自底向上遍历一棵树,可以记录拓扑序,每次逆拓扑序遍历,就不用递归了。

    真“高性能”题:

    P4135 作诗(没有优化的分块会被卡时间卡空间)

    P4718 【模板】Pollard-Rho算法(毒瘤卡时间)

    P3527 [POI2011]MET-Meteors(普通的整体二分会被卡时间然而我竟然用朴素算法卡过去了

    P3380 【模板】二逼平衡树(树套树)(卡Splay)

    P3759 [TJOI2017]不勤劳的图书管理员(Splay被卡得狂T不止,需要用树状数组套线段树)

    “另类”的卡常:卡空间

    一些毒瘤题竟然毒瘤到卡空间!比如:P5471 [NOI2019]弹跳P4148 简单题P6622 [省选联考 2020 A/B 卷] 信号传递P3592 [POI2015]MYJ
    。这样的题并不多见,但是一出现就很致命,毕竟我并不太会卡空间。

    可能用到的方法:

    • 时间换空间。即,当我们用到的时候现场算。

    • int 改成 short,bool 数组用 bitset 维护

    • 改变算法,如 st表 改成线段树,树套树换成K-D Tree。

    • ...

    附:

    快速读入

    template<typename T> inline void read(T &x) {
    	x = 0; char c = getchar(); bool flag = false;
    	while (!isdigit(c)) {if (c == '-') flag = true; c = getchar(); }
    	while (isdigit(c)) {x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); }
    	if (flag)	x = -x;
    }
    

    快速输出(不常用,一般用printf即可)

    template<typename T> inline void Write(T x) {
    	short stk[30], top = 0;
    	if (x < 0)	putchar('-'), x = -x;
    	do stk[++top] = x % 10, x /= 10; while (x);
    	while (top)	putchar('0' | stk[top--]);
    }
    
  • 相关阅读:
    .NETCore_初探
    .NETCore_生成实体
    架构碎屑
    Helper
    26.【转载】挖洞技巧:绕过短信&邮箱轰炸限制以及后续
    25.【转载】挖洞技巧:支付漏洞之总结
    24.【转载】挖洞技巧:信息泄露之总结
    5.Windows应急响应:挖矿病毒
    4.Windows应急响应:勒索病毒
    3.Windows应急响应:蠕虫病毒
  • 原文地址:https://www.cnblogs.com/JiaZP/p/13567177.html
Copyright © 2011-2022 走看看