zoukankan      html  css  js  c++  java
  • 时间卡常技巧

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

    先放一句话镇场:

    我觉得,卡常数的出题人都是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

    ①IO优化

    快速读入与快速输出。

    ②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;


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

  • 相关阅读:
    ServletConfig类
    坑爹的去哪儿网订酒店经历
    python + opencv + pycharm +语音生成
    最近看到的工作要求
    pip in windows
    路由器外接硬盘做nas可行吗?
    阅读201706
    scrum学习
    学习concurrency programming进展
    Reactor/Proactor的比较 (ZZ)
  • 原文地址:https://www.cnblogs.com/AK-ls/p/11526813.html
Copyright © 2011-2022 走看看