赛事备忘录(legacy ver.)
系统相关
Linux
标准编译器版本为 g++ 9.3.0(见官网)。望周知。
推荐编译指令 g++ -std=c++14 -O2 -Wall -Wextra -Wconversion -Wshadow
请不要省略 -std=c++14。
备选参数:
-Wpadantic严格 ISO 模式。-fsanitize=address,undefined检测 UB(性能急剧下降)
对拍脚本:
export CPPFLAGS='-std=c++14 -O2 -Wall -Wextra -Wconversion'
make xxx gen brute # 编译
if [[ $? -ne 0 ]]; then
echo "Compile failed."
return 1
fi
while [[ true ]]; do
./gen > 1.in
./brute < 1.in > 1.ans
time ./xxx < 1.in > 1.out
diff 1.ans 1.out # 比对输出
if [[ $? -ne 0 ]]; then
break
fi
done
常用命令:
/usr/bin/time --format='%Us [%S systime] %MKiB' ./xxx测时间+内存joe xxx.in安全打开大样例(见这里)ulimit -s unlimited当前终端无限栈空间。对于部分配置较低的电脑可能有点危险,可以使用ulimit -s 131072代替。(131072 = 1024 \times 128 )size xxx测静态内存,一个程序的静态内存即为输出中的dec。(单位为 Byte)
经测试,ub-san, -Wconversion 都不会对以下情况警告:
- 用
pair<int, int>遍历vector<pair<long long, long long>> - 把
long long隐式扔到参数类型为int的构造函数里面。常见于emplace系列。
Windows
推荐编译指令:g++ -std=c++14 -O2 -Wall -Wextra -Wconversion -fno-ms-extensions
备选参数:
- 同 Linux。
-Wl,-stack=134217728开大栈空间。
对拍脚本:
@echo off
:loop
gen.exe > 1.in
brute.exe < 1.in > 1.ans
xxx.exe < 1.in > 1.out
fc 1.ans 1.out
if not errorlevel 1 goto loop
pause
goto loop
以及对应的 powershell 版本 (2024.8.16 更新)
while ($True) {
./gen > 1.in
cat 1.in | ./brute > 1.ans
cat 1.in | ./xxx > 1.out
if ($(diff $(cat 1.out) $(cat 1.ans)) -ne $None) {
break;
}
}
常用命令:
cd /d E:(或直接 E:)终端进入 E: 盘
不建议 使用 Dev-c++。可以使用功能、界面相近的 Code::Blocks 替代。
语言相关
语言 feature
-
建议使用匿名 namespace 包裹函数(详见这里)。
-
#define chkmin(a,b) (a = a < b ? a : b)可能会使程序变慢数倍。理由:chkmin(f[x], query(y, z))可能会调用query(y, z)两遍,在某些情况下甚至可能导致 复杂度错误。另外请慎用宏定义。 -
size_t是unsigned类型,在64 位机器下为64 位整型。请注意比赛用机(Windows)有可能不是 64 位的(笔者并不太确定)所以请确保不要写出max(a.size(), 1)等状物,会在 Linux 下 CE。(以及printf一个size_t时最好强转成int或long long。) -
以上一条更广为人知的错法是 For(i, 0, a.size() - 1),在 a 为空时会出众所周知的大锅。
-
signed,signed int和int是一种类型。 -
signed char,char是两种类型。 -
标准只规定了
isdigit(ch)的返回值是int类型的0 / 非0 。 -
非静态整型变量初始值并不是
0 。 -
默认构造函数不会把
struct / class里面的非静态成员变量赋值成0 。 -
非
inline的 静态成员变量 在class/struct里面只是 声明,请在类外 定义,否则会在链接时 CE。
class A {
static int a;
};
int A::a = 1; // 如果没有这一行,会 CE:undefined reference to `A::a'
- 运算符优先级顺序 和 表达式求值顺序 没有任何关联。在执行有副作用的函数时尤其需要注意。
a[read()] = read(); // 在 c++17 之前是 UB
-
大括号初始化巨大数组会显著增加可执行文件大小,可能导致 CTLE。结构体内元素直接赋初值而非写构造函数同理。
-
int左/右移 32 位以上是 UB。 -
测静态空间:定义两个 bool 变量,一个放开头一个放结尾,取地址相减之后除以1048576 (1048576 = 1024\times 1024 )[ 结果单位为 MiB ] -
UPD:以上方法是假的,编译器可以优化内存存放位置。请使用 size 命令。
-
#define _GLIBCXX_DEBUG可以测 STL 的 UB。同时,其会显著拖慢程序的运行速度。 -
Lambda表达式递归 必须 按引用捕获,或者参数传this。 -
__int128的abs有锅,请不要使用。 -
unordered_map不支持pair,vector和__int128。