就是一个菜鸡的总结
1.代码类
1.有时候不开long long,所以以防万一只要有开long long的可能就直接全局long long,就是有时候需要注意内存。
2.字符串的读入总是令人智熄,所以可能的话统一用scanf,像类似线段树输入操作的时候就直接开一个字符数组,这样就不会被空格啊行末回车啊什么的按在地上摩擦。(PS:有字符数组的读入好像不能用fread了?)
3.调试语句一定要记得注释掉,或者用cerr,最后一定要用文件操作运行一下程序。
4.多组数据该清空的一定要记得清空!
2.实现类
1.阶乘的逆元是可以O(n)处理的,不要老想着快速幂,0的逆元也要给初值1.。
2.二分现在的写法要好看一点:
int l=1,r=n,mid,ans;
while(l<=r){
mid=l+r>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
这样就不用纠结输出l还是r了,直接输出ans即可,还不会死循环。
3.模拟一定要冷静,想想可能会出现的特殊情况和bug,思路要确保清晰,多打注释。
4.变量名要清真一点,避免在Linux下冲突。
5.最短路能迪杰斯特拉就不SPFA,除非他丧心病狂考差分约束。
6.线段树的标记下传的顺序问题,可参考数据结构题一题,标记下传的顺序会影响当前节点修改时某些变量是否改动。
7.动态开点的线段树记得数组要开够。
8.对于决策单调性这种东西学会打表。
9.打暴力的时候,能预处理询问的先预处理,不然复杂度多一个q。
10.注意一些常数的优化,不要老是给自己套一个log。
11.整除分块记得i=j+1。
12.遇到期望概率不要慌,可以上个厕所压压惊。正推倒推要搞清楚,初状态要明确。
13.遇到DP也不要慌,与实际意义挂钩推转移方程。
然后就是一些考试的时候应该注意的东西
1.不要把程序存在桌面,否则一旦出点问题就凉了。(有次差点遭了)
2.写出正解最好造点小数据和大暴力对拍,如果不是那种能很快写出正解的,先把最小的subtask的暴力打了,然后再去推正解,如果有更高的部分分的思路可以先留着,若超过30min没有任何进展开始写更高的部分分或者直接跳过。
3.根据数据范围判断算法
n<=10 | O(n!)-O(n*n!),枚举全排列 |
n<=20 | O(2^n)-O(n*2^n),状压DP,枚举是否选择 |
n=40 | O(2^(n/2)),折半搜索 |
n<=100 | O(n^3),Floyd,区间DP,网络流,高斯消元 |
n<=1000 | O(n^2)-O(n^2*logn),二维DP,枚举,二分+枚举区间检查 |
n<=50000 | O(n*sqrt(n)),分块,二分图匹配 |
n<=100000 | O(n*logn^2),二维树状数组,树剖,CDQ,二分图匹配 |
n<=500000 | O(n*logn),线段树,二分,树状数组,最短路,树形DP |
n<=1e6 | O(n),一般是线性DP,超纲一点就是斜率优化,贪心,单调栈 |
n<=1e18 | O(logn),矩阵快速幂优化转移,数论 |
n<=1e18 | O(1),结论题 |