我的错题本

最新版见我洛谷主页,这里用于备份,不定期更新

备份地址:

上次更新时间:2022/9/10

ZTX错题总结本

Part A 总纲/必须检查

  1. 题目是否看错(详见Part L)
  2. 数组是否开小或开大(详见Part D)
  3. 通读代码
  4. 就算会打正解也看完每档部分分,防止某些zz出题人每档部分分做法不一样
  5. 检查时每个for都看一遍,防止t掉
  6. 多测要清空(详见Part G)
  7. 边界条件考虑一下(详见Part H)
  8. 大常数题目可以适当考虑卡常(常见优化见Part I)
  9. 代码最好备份,大样例不要复制到代码上来,不然代码全没了
  10. 变量重名、用错
  11. freopen、文件名、文件夹名检查
  12. 想到一种做法后先代入样例验证是否可行,尤其是结论题、计数题、数论题、DP题、图论题、字符串题、数据结构题(感觉好像说了OI大半知识点
  13. 复杂度分析要正确,不要分析错复杂度导致算法不敢打或T飞了(见Part M)
  14. 调整好比赛心态(Part N)

Part B 易错常错

  1. 线段树要开4倍空间
  2. 背包问题注意不要重复调用
  3. DP注意边界条件,尤其是1和 \(n+1\) 的情况
  4. \(n,m\) 读入注意不要写反
  5. 三分前要思考函数会不会出现平台的情况
  6. DAG图上操作最好先拓扑一下,不拓扑必须使用滚动数组
  7. dfs 要用局部变量
  8. 倍增(包括RMQ、LCA等)第二维不要开太大,防止T掉。一般20就够了,不放心可以开到22
  9. 当出现多个 dfscmp 时不要调用错
  10. 位运算比较级还低于大于\小于\等于号,所以也要加括号
  11. 如果题目是树的时候输入要循环 \(n-1\)
  12. LCA如果要记录路上的值,要先记录,再修改点
  13. 后悔贪心要考虑怎么后悔最好,不要单纯后悔,贪心不用排序很有可能有漏洞
  14. 线段树单调修改写 ifelse 即可,区间才需要两个 if
  15. 线段树涉及区间操作时,如果要对这个区间做什么统计,范围是 \([\max(l,x),\min(r,y)]\)
  16. 异或如果是等式可以左右两边互移动,不等式异或不满足同异或性质
  17. sqrt() 如果不涉及浮点一定强制转化(评测机自动转不太对,最好加上 (int)
  18. 位运算涉及到ll要把1和0强制转换为ll,如果涉及到无符号要用1ull
  19. 网格转数值的时候要写 (x-1)*m+y 而不是乘 n 或者写 (m-1)
  20. 字符串长度 size() 返回是无符号整数,做减法可能出错,最后转为整数
  21. 函数要return,每种情况都要
  22. !运算符较高,比普通加减高
  23. 建模构图题连边时连的是编号还是数值要分清楚
  24. 特判的时候千万不要特判错(尤其是dp中特殊状态的转移)
  25. 后缀和如果不取下标应为 n+1
  26. dp如果用滚动数组的话每次记得清空,如果有 += 的话要判断之前是否存在直接赋值(而且这个直接赋值不在某些 iffor 里)
  27. 用Floyd判最短路时要注意不仅要判断 \((k,i)+(j,k)\),还要判断 \((k,j)+(k,i)\)
  28. 最长路要用大根堆
  29. 函数内使用全局变量要重点留意全局变量是什么,是否改变(ABC266F因此调了半小时)
  30. double取绝对值要用 fabs()
  31. 打标记的地方不要重复统计,加个判断是否打过标记(牛客练习102A)
  32. 主函数特判时一定要return 0(ABC267B RE*2)

Part C 算法选择

  1. 除非绝对保证,在能优化复杂度的前提 下(一般指优化 map 的log),不然能打离散化就打离散化
  2. 可以用线性筛解决的坚决不打埃氏筛,埃氏筛只能拿来对拍
  3. 如果很清晰能使用树状数组用树状数组,最稳妥打线段树,但容易打错
  4. 数学题(尤其指计数题)如果要大量用逆元、快速幂而要用的东西可以预处理就预处理,除非复杂度很大,别打线性求逆元,会打错的
  5. 能用二次剩余就不要扩域(一般二次剩余题目会有很奇怪的质数)
  6. 打Dinic加稳定dfs时最好把当前可流的流量丢到参数里,不要用数组存
  7. 打spfa时最好打上个标记优化
  8. 如果类似背包的东西放置物品有顺序就不能用背包,要把枚举物品放到最内层循环。

Part D 数组空间

  1. 注意图论题,分清楚每个数组和点还是边有关
  2. 注意以线段树为主的数据结构题,像线段树开4倍空间
  3. 注意环形类、双端点类需要2倍空间题注意大小
  4. 注意是否爆空间。 计算方法:数组大小乘字节数(int4 ll8)除两个1024
  5. 如果以值域为数组里面最好要开2倍,不要一加一减可能就2倍了
  6. 涉及二进制方面的数组最好开2倍
  7. 如果某个dp或类似的东西可能爆空间,考虑滚动数组

Part E 题目思考

  1. 20以内考虑爆搜或状压
  2. 1e5左右可考虑根号做法,尤其考虑根号分块
  3. 40以内(而且有20的部分分)一般是折半搜索
  4. 序列问题如果可以转化为某个位置操作尽量考虑线段树优化
  5. 后悔贪心类题目可以考虑用队列维护当前可行转态
  6. 某些dp或操作如果有太多重复操作可以考虑暴力跳
  7. 树上非套路题(非树形dp、LCA)可以考虑从叶子节点、树的度数方面来考虑(常见如CF结论题、构造题)
  8. 涉及到不带修改构造区间使得最大值最小值出现什么的问题一般可以考虑最大最小值在两个端点,有时也可从整体最大最小、次大次小来考虑
  9. 构造题一般可以从奇偶方面来思考
  10. 涉及到区间取模或开根等问题可以考虑开多次之后这个数会变成怎样或相邻两数之间的差的变化来思考
  11. 非传统数学类 \(\gcd\) 问题可以从辗转相除的角度来考虑
  12. 涉及到平面上覆盖问题可以考虑扫描线
  13. 如果线段树上有写东西很难下传可以考虑标记永久化(常见:李超线段树)
  14. 如果涉及前缀或区间异或值可以考虑以4分组,异或值每4个数一个周期,异或出来是0(ABC121D)
  15. 如果一些题实在想不到看一下能不能从特殊性质推出随机化的做法(牛客练习92E)
  16. 部分Floyd题目可以通过记录中转点来计算(ABC243E)
  17. 如果最短路连边很奇怪(而且有负环不能有Dij)可以考虑最后答案加减一些东西来换边权(ABC237E)
  18. 如果一道题目解一定但答案要求输出精度不大于 \(10^{-3}\) 之类很大概率是二分三分(ABC236E)
  19. 中位数也可以像平均数一样二分,大于等于他的记为1,小于记为-1,然后判断结果是否大于等于1(ABC236E)
  20. 序列构造题可以从插入数的方向考虑(0903模拟赛A)
  21. 树上问题尽量转化成染色问题(0903模拟赛B)
  22. 显然有些规律但难推的dp可以写出前几项找规律(ABC247F)

Part F 常见优化

  1. 状压类位运算类题目可以用 lowbit()popcount() 优化
  2. 常见序列上dp优化最多情况下考二分优化 、单调或优先队列优化、数据结构(线段树、树状数组)优化
  3. 线段树上二分如果常数过大考虑树状数组上二分
  4. map访问时要先 find() 一下,不然每次会新建节点导致 \(\log\) 复杂度大幅度增长

Part G 多测清空

  1. 每个变量、数组都思考一遍(尤其是队列
  2. 清空时不要把数据组数 \(T\) 或在 while(scanf("%d", &n)!=EOF) 中的 \(n\) 清掉
  3. 清空最好复原到全0状态,某些数组或变量要赋值无穷大、无穷小或 -1在后面再弄
  4. 清空最好写成函数 init()
  5. 对于数据组数 \(T\) 很大时不要用 memset(),考虑每个变量哪些要赋值,最稳妥是直接循环 \([1,n]\) 一遍清空
  6. init() 函数写好后一定要在主程序调用
  7. 把题目样例数据间顺序调转多测一测
  8. memset() 时不要 sizeof(0)
  9. 多组数据可以把打样例复制几遍来测

Part H 边界条件

  1. DP题目重点考虑边界情况,如 \(0、1、n、n+1\)
  2. 数论题目考虑除数、模数为0情况
  3. 组合数学推式子时尤其注意上下界问题
  4. 对于题目中的无解情况,要分类讨论,只有满足题目所有给定条件才是有解
  5. 对于特判情况,要思考所有要输出的怎么输出

Part I 常见常数优化

  1. 变量 register,函数 inline
  2. 善用位运算进行优化
  3. 重复的加减取模运算可以拿个变量存起来
  4. 多用常量
  5. 善用 memcpy() 代替复制数组操作(常见是滚动数组的情况,但滚动数组用 i&1 会更好)
  6. 多维数组尝试降维
  7. 快读快写

Part J 取模问题

  1. 计数题取模时最好每做一次操作都取模
  2. 部分题目如果某些数后面还要有大小比较或排序等操作的话不能先取模(这些情况一般可以写组大数据测下)
  3. 注意取模是否为质数。如果取模是质数,直接套快速幂。如果不是质数,要套拓欧。拓欧记得满足 \(\gcd(a,p)=1\)
  4. 如果某些题目不能在中间取模,但不在中间取模会爆的话要考虑其他做法

Part K 做题习惯(先咕着,赛前再补)

  1. 编译器默认先开个 -Wall

Part L 阅题方法

  1. 先通读题目,不要看一堆东西很烦自动跳过,每一个字都要看
  2. 看清题目中重点内容,例如是子串还是子序列,单调上升还是单调不降,大于还是大于等于,每个数是否只出现一次
  3. 看题目要求什么,不要打了一大堆代码才发现不是求这个(就因为这样某次CF直接下了100)
  4. 看输入输出格式,看清楚是怎么输入进来的,要输出些什么,留意多组数据怎么输入的,如果某些恶心ACM题目还要输出什么 Test %d
  5. 看样例,一定要把样例看懂,才开始想
  6. 看数据范围,数据范围如果有特殊地方很有可能是入手处(可以参考Part E)
  7. 看特殊性质。某些题目可能有:每个数只出现一次,某个操作出现次数不超过多少次,也许就是切入点
  8. 英文题目最好看2次、
  9. 字符串题留意字母出现是大写或小写,是出现 AZ,还是或者一些其他题目只出现 AI 什么的(某次J组OI模拟赛因此痛失AK)

Part M 复杂度分析

  1. 经典树形dp如果复杂度看起来是 \(O(n^3)\),本质上是 \(O(n^2)\),具体可以想成两颗子树合并相当于所有lca为当前点的节点合并,所以每对节点只会合并一次

Part N 比赛心态/习惯/经验

OI赛制

  1. 如果T1不会不要想着后面几题打部分就算,T2T3每题至少给半小时想正解(220903模拟赛)
  2. 每场比赛肯定有送分题,不是T1就是T2T3(220903模拟赛)
  3. 每题都要看,说不定最后一题部分分很好打(220907模拟赛)

ACM赛制

  1. 如果对拍出错千万不要交(ARC147)
posted @ 2022-09-10 17:40  zhangtingxi  阅读(149)  评论(0编辑  收藏  举报