ACM技巧记录

1 常量值记得加const,有助于优化器优化

2 linux的strstr是优化过的,比KMP快

3 for循环判断不要使用计算值

for(int i=0;i<strlen(a), i++)

4 FFT中的模

a += M & (a>>31);

其目的是将[-M,M)中的整数模M,即变成[0,M)中的数。

其正确性依赖于GCC规定负数右移的规则按算数右移的规则,即负数右移最高位补1。

5 读入挂的使用

参考链接:https://blog.csdn.net/xs18952904/article/details/76768791

c++中:

在ACM里,经常出现数据集超大造成 cin TLE的情况。这时候大部分人(包括原来我也是)认为这是cin的效率不及scanf的错。其实像这只是C++为了兼容而采取的保守措施。我们可以在IO之前将stdio解除绑定,这样做了之后要注意不要同时混用cout和printf之类。

在默认的情况下cin绑定的是cout,每次执行 << 操作符的时候都要调用flush,这样会增加IO负担。可以通过tie(0)(0表示NULL)来解除cin与cout的绑定,进一步加快执行效率。

#include <iostream>
using namespace std;
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    return 0;
}

错误方式:

#define read read()

struct P{
int x, y;
P(int xx, int yy):x(xx), y(yy{});
};

int main()
{
 P p(read, read);
}

由于这样的read写在构造函数中,读入的顺序不确定,容易产生bug

但是可以这样写

P p{read, read}

因为语言标准要求初始化列表中的元素必须做左到右求值

6 加入INF,NAN异常,来帮助找到错误

#include<iostream>
#include<cfenv>
#include<cmath>

using namespace std;
int main(){
    feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFOLW);
    double a=-1, b=0;
    cout<<sqrt(a/b)<<"\n;
    return0;
}

7 对拍

generator.py

from random import randint ,seed
seed(int(input()))
n = randint(1, 10)
print(n)
print(" ".join([str(randint(1,100)) for i in range(n)]))
#!/bin/sh

for ((i=0;;i++)) do
    echo $i | python3 generator.py > dara-$i.in
    ./brute < data-$i.in > data-$i.ans
    if | ./solution < data-$i.in > data-$i.out; then
        echo "runtime error on test $i"
        break
    fi
    if diff data-$i.ans data-$i.out; then
        rm data-$i.{in,out,ans}
    else
        echo "wrong answer on test $i"
        break
    fi
    echo "test $i ok"
done

8 调试使用GDB

打比赛主流工具是codeblocks和文本编辑器vi等。

相对来说GDB是较好的调试器

文章目录