犯错和注意
1.矩阵乘法乘的时候一定注意是否要开\(longlong\)。
2.确保暴力正确再对拍.
3.线段树\(tag\)标记一定要看清楚,有多个时不要搞混。
4.倍增求\(lca\),次方循环放外面。
5.打树剖时,线段树用的是\(dfn[x]\),树剖用的是x。
6.分块,正经的分块
n = read(); t = sqrt(n);
for(int i = 1;i <= n; i++) c[i] = a[i] = read(), pos[i] = (i - 1) / t + 1, b[pos[i]].l = 23333333;
for(int i = 1;i <= n; i++) b[pos[i]].l = min(b[pos[i]].l, i), b[pos[i]].r = max(b[pos[i]].r, i);
不可以这么分
n = read(); t = sqrt(n);
for(int i = 1;i <= n; i++) c[i] = a[i] = read();
for(int i = 1;i <= t; i++) b[i].l = (i - 1) * t + 1, b[i].r = i * t;
if(b[t].r < n) b[++t].l = b[t - 1].r + 1, b[t].r = n;
for(int i = 1;i <= t; i++) for(int j = b[i].l;j <= b[i].r; j++) pos[j] = i;
7.优先队列内结构体的重载
大根堆:按num从大到小排序
struct people {
int id, num;
friend bool operator < (const people &a, const people &b) { return a.num < b.num; }
};
priority_queue <people> q;
小根堆:按num从小到大排序
struct people {
int id, num;
friend bool operator > (const people &a, const people &b) { return a.num > b.num; }
};
priority_queue <people, vertor<people>, greater<people> q;
8.void类型的函数千万不要写成int类型。
9.扫描线,如果有几条纵坐标相等的线,先扫下界(1),再扫上界(-1)。
10.dij不适用于有负边权的图!!!!
11.代码的注释一定不要弄错,哪里该注释掉,不该注释掉都要搞清楚。
12.有的时候快速幂传进去的参数是long long类型的,注意先mod一下再乘。
13.做矩阵乘法题赋初值,\(n = 1\)时可能不太一样.\(a[i][j] = 1\)变成\(a[i][j] ++\);
14.SPFA判断负环是\(cnt[x] > n\), 不是\(cnt[x] >= n\).
15.输入字符串或字符用cin肯定不会错.
16.多卡常, 例如快读, 能开int不开longlong等.(该开longlong一定要开)
17.线段树开4倍空间,双向边开双倍空间,这里要多检查.
18.少用map, 能不用就不用.
19.输出double用"%lf", long double 用"%Lf".
20.树上路径问题要考虑点分治, 但是写点分治之前要考虑是否可以快速的统计答案, 也就是是否可以做到降低时间复杂度.
21.思路清晰了再写代码, 一定要想全, 否则打了一半发现不对很浪费时间.
22.同样的操作重复次数很多的话, 可以考虑矩阵或倍增.
22.正难则反, 单步容斥这些多考虑考虑.
23.多写函数, 结构体封装也可以写一写, 尽量把代码分成一块一块的.
24.有些东西不好维护, 看看能不能化成别的形式就好维护了, 比如\((a + b) ^ 2 = a ^ 2 + 2ab + b ^ 2\).