遇题初反应
sb操作/nb技巧 集合
- 数据极限算错了没开long long, 把每个东西都算极限,实际东西有若干倍看见算错了,导致爆空间/数组开小。
- 手造的极限数据不极限,查不出来上面两个,所以要仔细算,空间直接sizeof别自信,不爆空间不卡常,数组多开加define int long long。
- 变量打反了。
- 顺序读完所有题再开题,不要一开场扎到一个题上,会的分必须写完。
- 取模取少了(-x直接变成加 P-x,不用担心取模少)。
- 建线段树的时候记者看在哪开的线段树,别直接把上标写成n。
- 打表就傻乎乎打个表,不观察性质,不对打出来的东西凑一凑,猜一猜。
- 强制在线,没更新lastans。
- 逗号分号搞错,if 作用范围错误。
- 用 read() 读浮点数。
- 题意不是很清楚,不模样例做半天假题。
- 看数据范围不大就打个sb算法认为能过,不算复杂度,不看多组数据,没想nt优化。
11. 复杂度要仔细算!状态数*转移数,尤其是均摊型的题,摔倒坑里就死惨了! - 认为数据范围不小就认为过不了,不算复杂度(\(2^{28}=2e8\))
- 均摊复杂度算错,自信的打出一个暴力认为是正解。
- 根据11,12,13,我们总结出,打任何算法都要算复杂度,不管是暴力,还是一个划过脑子的想法。
- 高精度别忘记可以压位。
- 有特别复杂的边界的时候,不妨花些时间取思考怎么搞个操作让边界简单一些,往往能省下很多讨论的时间。
- 结构体里面不能直接赋值,要写初始化函数,否则编译TLE。
- 写记搜要记忆化,只有01的记搜(尤其是博弈记搜),可以开一个当vis,开一个当值,两bitset换一个int
- 逆元是完全积性,别那么喜欢快速幂。
- 给暴力留太少时间,连基本的思考都没有,容易拿不到Sb送的分,时间分配不能过偏。
- a[x] = x = ++cnt, 是经典 UB,闲着没事不要把一个变量多次出现在一个连等式里面。
- 如果vector内需要push很多元素,可以考虑换成邻接表卡常。
- 先把题看对再做题!! 题目读三遍!! , 8.8, 明天题目必须读清楚再开题,至少三遍。
EI Orz
问题解决的指导原则(试用版)v0.0.1
-
为达成有效的思考,有时我们需要平静下来,摒弃急躁,然后根据如下文等一系列方法达到终点。
-
面对一个庞大、复杂的问题时,将问题进行拆分,逐个尝试解决,如果仍然没有思路,则从最为简单的例子出发。或者说,考察这个问题是否有些你熟知的,已经解决的特例。然后,分别比较:这个特例和整个问题之间的关系是什么样的?这个特例的解决途径又有可能在整个问题的解决中具有何等地位?
-
另一个方向则是,尝试将问题进行泛化。这个问题能否归于某个你熟知的更具有一般性的模型,或者至少与其他模型是否有相似之处?比对大问题与小问题的一般性和特殊性。
-
尝试借助各种工具,或者各种类型的直观。其一是用图上几何直观,借助几何图形在大脑中的呈现来考虑问题。其二是符号演算,利用基于符号所重塑的新直观来进一步考虑问题。不要拘泥于某一种特定的方法,在各种视角之间不断变换!
-
面对非常困难的问题,要有长足的耐心和不懈的斗志。从一切可能的事物中汲取灵感:数学、自然科学、文学、艺术……
-- From EI.
Small Tricks
本篇 Blog 用来记录见到题应该有的第一反应,来避免很多基础的东西没想到的行为。
- 先把题看对再做题!! 题目读三遍!!
- 先把题看对再做题!! 题目读三遍!!
- 先把题看对再做题!! 题目读三遍!!
- 先把题看对再做题!! 题目读三遍!!
- 遇到一道题,先从小规模的样例观察,发现其中的规律。
- 观察基本的性质,适当猜结论,证明或者打表验证。
- 二分答案把最有化转成判定, 二分答案求排名。
- 答案有单调性,直接想二分答案!!
- 题目给出的东西是区间,立马可以想差分,前缀和。
- 走投无路不妨思考能不能暴力 Dp, 策略思考一些基本策略,实在无方法可以考虑建图。
- 一类最优化问题,可以考虑不必维护所有正确的值,只要能保证最大值正确就行了。
- 可以先思考有关最值的部分,看最值决定什么性质,尤其是各种求 max 的题。
- Dp 的基本优化:
- 前缀和,单调性,斜率,矩阵,数据结构,倍增,决策单调性(跟最优化有关的直接打表), 长剖重剖。
- 什么问题都要先想想这个东西的上下界,可能化腐朽为神奇
-
- 什么问题都要先想想这个东西的上下界,可能化腐朽为神奇
- 排除不可能决策,例如把区间搞成一个端点排序后另一个端点单调。
- 不等限制很多的时候往往有一些简洁优美的贪心策略,尝试去捣鼓不等关系。
- 模拟题倒着离线模拟一遍,和添加、删除有关的都可以考虑倒着走。信息不对称的题倒着搜。
- 线性性拆开贡献。
- 扫描线加入比较复杂可以考虑每次删除,回滚莫队同理 (比如求 mex)。
- 曼哈顿距离转切比雪夫距离
- 分治
- 求全局去掉某一个地方的值,考虑分治。
- 求\(n^2\) 种全关系,考虑分治,每次计算 \([l,mid]\) 和 \([mid+1,r]\) 的关系。
- 若一层的关系可以同时处理,复杂度可以 \(O(logn)\) ,(GZOI2019 旅行者,一道考试的交互,CF1365G)
- 若 \([a,b]\) 的贡献可以拆成 \([a,c]+[c+1,b]\) ,那么对于每个右端点考虑最靠右的区间计算贡献,区间个数是O(n)的,只需要看每个区被算几遍。
- 权在点上的最短路,复杂度是 \(nlogn\), 每个点只会入队一遍。
- 向量乘矩阵是 \(n^2\) 的,可以处理出来每个 \(2^k\) 的矩阵,最后拿一个向量把他们一个一个乘起来。
- 折半搜索似乎是个好东西,\(2^n\) 能硬生生优化成 \(2^{(n/2)}\)这样子的,主体算是分治。
- 求期望不要执着于求概率,可以考虑设计期望 Dp, 状态为到终点的期望。
- Gcd, 线性基都是可以差分的,用来对付区间修改。
- 询问太多,离线存不下?考虑一下分组离线。
- 当有若干连续段的时候,若合并不重要(只关心一个地方被覆盖几次/被不被覆盖),可以考虑使用括号序列表示连续段,前缀和大于0的位置被覆盖,一般可以在想到 ODT 的时候考虑一下
- 有关环的构造,优先考虑欧拉回路,他是图论上构造的一大法宝。
- 断环为链:考虑扩展一倍变成序列,前提是你需要保证最优方案一定存在一个断点。
- 也可以考虑一次强制连接一个地方,一次强制断开一个地方分别计算贡献,即可考虑全部情况。
- 树上一类需要跳 Fa 的可以考虑点分树去优化,点分树优化不了的就是需要在 LCA 统计信息的,这类可以考虑枚举LCA然后 Dsu on tree 做到 \(\sum siz_{\text{轻儿子}} = nlogn\) 的复杂度。
- 一类无环时可以直接拓扑排序的题,有环可以考虑搬到最短路上,或者考虑在 ans 上拓扑排序, CF1693C, 同时也提供一个思路,有向图有环的时候不会做先思考无环怎么做。
- 高斯消元解方程的时候有一个套路,就是设置主元,假设你知道这些变量,然后把每个地方用系数表示出来,最后解出主元,一般可以用在变量之间关系稀疏的时候优化复杂度,也是高斯消元不多的套路之一 NOI 4.30 T2 , NOI 6.20 T2.
- 有关对位的操作,不要多思考,绝对没戏,只能考虑类似线段树合并,bitset,分块之类的东西。
- Dp是布尔值,优化思路是考虑单调性重新设计状态或者考虑使用 bitset 。
- 对于 +1,-1的背包,可以考虑随机打乱,前缀和是 \(\sqrt n\) 的,以来减少复杂度。
- 字符串 \(AB\) 变成 \(BA\) ,除了认为他是交换也可以认为他是循环左移 \(|A|\) 位。
- 题目里面各种 \(2^k\) 相关的东西,考虑把信息写成二进制。
- 黑白染色用处有很多,网格图,相关联的两个对象都可以考虑染色分成两个独立的集合!
- 把两两之间的关系看成边会有奇妙的效果!联通块一般都有实际意义!
- 树形图不要考虑成DAG!把他当树做,分类讨论正边和反边。
- 计数题实在走投无路,考虑计和他等价的东西的数量,也就是双射,双射的基本东西是打表,通过打表发现原题和什么之间有双射,在考虑去构造。
- 题目给出了若干种操作,要求构造/最小化操作次数,一个思路是看能不能把一种操作转化成另一种或者用几种操作构造一个新操作。
- 题目是删除,能离线,考虑时光倒流,添加很容易,考虑线段树分治。
- 见到位运算相关,不要忘记位之间独立,Trie树,线性基,按位贪心,FWT。
- \(\sum_{i=0}^n \frac{1}{2^i} = O(1)\) ,计算复杂度的时候通常可以改变求和顺序发现复杂度并没有 \(log\) 。
- 钦定在一个集合考虑捆绑!!!
- 有操作的题考虑把操作转化成连边,有的能加快理解,有的则是解题要道。
- 容斥千万不要思维定式,比如说要求0个不合法,就想着枚举多少个不合法,时刻记住目的,让不合法算0遍而不是套模板!
- 环的实现很困难,优先想断环为链!!!
- 选择一个排列,如积和式,行列式,可以考虑二分图匹配, 一些地方有特殊值,把特殊值拆成平凡值+增量。
- Border,回文等的字符串问题,一定要多画串串找性质!
- 在线的时候需要倍增,离线的时候可以考虑从根到每个点 dfs 一遍,在每个询问的点二分,去掉 n 上的log, 可以离线的时候优先考虑怎么优化这些可以在线的做法。
- 一类计数问题,先想怎么判断合法,有特殊性质可以根据特殊性质编做法,有 dp 做法可以考虑 dp 套 dp。
- 看到特殊的代价函数要根据代价思考做法,比如代价是 \(2^i\) , 就可以考虑把东西从大到小摆开按位贪心。
- 在一张图中,若点数/边数比较多,可以考虑缩一度点/二度点等等,边-点很少可以考虑建树枚举非树边。
- 一些数据结构问题,求某个东西的值,经典做法是考虑某个值包含的所有东西,总之,在不同的维度之间不断切换角度去考虑,提供了很多入手点。
- 有关变化量很少的问题优先考虑扫描线!
- 查询不交区间:在 \(l_1\) 把 \(r_1\) 插入,在 \(l_2\) 查询 \(r_2\) , 这样保证了 \(l_1 \leq l_2 \And r1 \leq r2\) ,不合法的情况是完全不交,一般容易容斥掉(这个主要是去掉包含和被包含),这个还是说不要思维定式,不要低估扫描线的杀伤力,把你想干的试试,没准就有戏。
- 统计树上符合条件的路径/最优的某种路径:可以考虑换根dp,钦定一个点是出发点简化问题,还有一个经典套路是 \(f_{x,i}\) 代表 \(x\) 子树内由 \(0/1/2\) 个路径端点。
- 求最值的问题首先分离独立的部分!
- 求最少删掉多少经典是求最多保留多少
- 最短路的堆可以用 \(W\) 个队列代替, \(W\) 是值域。
$The \ light \ has \ betrayed \ me$