SB 错误

多测要清空! 多测要清空! 多测要清空!
开long long! 卡常时不用 ll! 开long long!
inf 不能设小! 也不能太大!
记得算内存! 估算会不会MLE! 记得算内存!
freopen! freopen! freopen!
交前删调试! 交前删调试! 交前删调试!

开数组空间要开够

估算会不会MLE

链式前向星 idx 初值为 0 或 1 写法不同

初值为 1

1
2
3
4
5
#define enr(i, u) for(int i=h[u]; i; i=ne[i])

inline void addedge(int a, int b) {
e[idx] = b; ne[idx] = h[a]; h[a] = idx++;
}

初值为 0

1
2
3
4
5
#define enr(i, u) for(int i=h[u]; i; i=ne[i])

inline void adde(int u, int v) {
ne[++idx] = h[u]; h[u] = idx; e[idx] = v;
}

或者

1
2
3
4
5
#define enr(i, u) for(int i=h[u]; ~i; i=ne[i])

inline void addedge(int a, int b) {
e[idx] = b; ne[idx] = h[a]; h[a] = idx++;
}

并将 h 数组初始化为 -1

要看清楚题目的输入输出

写代码的时候不能忘记读取数据或输出答案。

循环的边界要注意

1
2
3
4
5
6
7
8
9
void primeseive(int n){
for(int i=2;i<=n;i++){
if(!st[i]) primes[cnt++] = i;
for(int j=0;primes[j]*i<=n;j++){
st[primes[j]*i] = 1;
if(i%primes[j] == 0) break;
}
}
}

2 行中的 i=2 如果写成 i=0, 将会导致死循环

二维数组边界特判, 大于取等于, 小于就不能取等于, 以保证不漏取不多取:

1
2
3
...
if(x2>=0&&y2>=0&&x2<n&&y2<m)
...

动态规划想清楚状态表示, 并相应初始化

要注意代码的逻辑顺序

区间合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int merge(){
vector<PII> tmp;
sort(seg.begin(),seg.end());
int l = -2e9,r = -2e9;
for(auto s:seg){
if(r<s.first){
if (l != -2e9) tmp.push_back({l,r});
l = s.first, r = s.second;
}
else{
r = max(r,s.second);
}
}
if(l != -2e9) tmp.push_back({l,r});
return tmp.size();
}
1
2
if (l != -2e9) tmp.push_back({l,r});
l = s.first;r = s.second;

两行不能调换位置,否则会把第一个区间加入答案中,导致一些情况中结果多了一个。

不过在区间合并中只要区间个数不为零,最后个数一定会加一,所以这意味着我们在调换这两行的位置后,再将最后的 if(l != -2e9) tmp.push_back({l,r}) 删去,,最终结果也是正确的,不过 tmp 中的区间具体情况就不对了。

字符串

字符串类型转化

字符(char)转整型(int)要记得减去 '0'

C++ 语法

namespace 在 typedef 前

函数中需要的全局变量不可在main函数中重新定义

慎用宏定义

1
2
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) > (b) ? (b) : (a))

这个宏定义不可以传入函数, 因为这样会导致函数有几率被多算一次, 直接是复杂度增大一个量级(在递归中), 所以很可能会导致TLE.

%lld 而不是 %I64d

因为CCF评测机是Linux系统, long long%I64d 输出会导致 WA.

流同步关闭后不可同时使用cstdioiostream

ios::sync_with_stdio(false) 之后不可同时使用 scanf printf puts 套装 和 cin, cout.

注意运算符优先级

  • 取模运算优先级高于加法

  • 位运算优先级低于四则运算