思路:
- 知道什么东西在变化,什么东西没有变化。
关于超时(cf上大概能跑1e8):
- 写之前先算算复杂度,如果\(n^2\)超时了,那可以考虑一下\(nlog(n)\),用二分可以降低复杂度
- 当可以由一个东西或者两个东西确定另外一个东西的时候,我们最优办法是直接得到我们要的东西,然后看总量中是否存在这样一个东西,而不是分别遍历每一个元素,再判断其是否符合条件,这样就可以降低一个\(O(n)\)的复杂度。
a^a=0
stack
和vector
都可以在递归函数中调用,用以保存数组,stack
处理时间长(约为vector
2倍),但空间小,vector
处理时间快,但空间大(约为stack
的10倍)- 对于模进之类的思维题,最好是
for
循环里面套一个while
,这样出错率低 - 当递归的规模很大,并且有很多重复运算的时候,可以采用记忆化
- 对于一个东西,如果它可以单调性的话,考虑使用二分,或者实在想不出别的解决办法,直接二分答案
- 在面对数学问题的时候,可以考虑解方程,来简化运算,并且得到思路
- 从很多边中选三条边构成三角形,最优解是相邻三条边\((a[i-1]<=a[i]<=a[i+1])\),对该问题的证明是:先固定住最小边\(a[i-1]\),来看剩下两条边,要使两边之和大于第三边,两边之差小于第三边,最优的办法说使这两个数尽可能大,并且这两个数一定要挨在一起,这样才能使两边之差最小,而要让最小边大于两边之差的最优解也是正好与这两个数相邻,且小于它们,因此最优解就是相邻的三条边。
- 从一个数 n(不能被10整除) 变成末尾有几个0的数,要想到的一点是,10只能由2和5变成,先看 n 里有几个2或者几个5(两者不能同时存在,不然 n 里就会有10了),然后用5把2变成10,用2把5变成10。
- 如果是求一段区间
l~r
内的值,可以考虑用一个函数f(x)
求出求出1~x
的答案,那么最后的结果就是f(r)-f(l-1)
- 进行四舍五入的操作,例如对 x 保留2位有效数字
round(x*100)/100
- 对于暴力题,如果实在想不出啥其他很神的办法的话,那么就应该去思考怎么去优化它的计算,减少重复计算
- 对于0011011000111,如果我们要删去0使得1都在一块,那么我们不必去求夹在1中间的0的个数,最便捷的方法是求1的最左端和最右端,再统计最左端和最右端之间0的个数即可。
- 对于一些有单调性的数学问题,如果直接计算很麻烦的话,不如考虑一下二分答案,然后check一下看是否满足要求
- 把数据列出来有利于看出规律,不要一股脑的只用脑袋想
- 特别是对于数学问题,当正面计算很复杂的时候,尝试一下用总的方案数减去不符合条件的方案数,说不定会简单些,这是利用的容斥的思想。
- Python内置的
pow(x,n,mod)
函数的复杂度是\(O(log(n))\),甚至比快速幂还要更快 - Debug方法之一 —— 判断边界数据是否可行。
- 可以由最终结果在有限的步骤之内推出可能的起始状态。
- 对于字符串问题,如果对于下标进行操作复杂度很大的话,可以考虑对字母进行操作,这样计算复杂度的时候就是对26进行计算了。
- 通过数据范围,揣测复杂度的可能构造方式。
语法:
-
memset
只能用于初始化数组为\(0\)或\(-1\),其他的可能会出错,最好用for
,fill(begin,end,value)
函数也可以。 -
动态开辟数组:
vector<vector<int> > a(n+5,vector<int>(m+5));
相当于
a[n+5][m+5]
-
vector<int> a;
(int)a.size()
要加int
转化不然就有可能出错,因为size
型的变量不可能有负的,所以当size-a<0
时,就会出错,所以此时应该需要强转 -
优先队列默认
top()
是最大值,如果写成priority_queue<int,vector<int>,greater<int> >
top()
则为最小值 -
在用位运算的时候一定要记得打括号,不然会出错,例如
1^1+1
它不是等于1,而是3,所以正确写法应该是(1^1)+1
-
如果优先队列中存的是自定义的结构体,那么就需要重载结构体的运算符,该运算符应该定义为全局的,不要放在结构体内部
注意事项:
- 要记得看数据大小,用
long long
还是int
,并且long long
的无穷要足够大 - 在对照别人的代码写的时候,如果出现很难找的 bug,解决方法是先理解代码的思路,然后把自己写的代码按照这个思路看一遍下去,看看能不能发现什么错误。
- 注意特殊数据的判断
- 互质指的是两个数的公约数只有1
- 写 bfs 的时候要注意的一点:要在 push 新状态的时候就将其
vis[]
置为1,不要等到遍历的时候再置为1,不然会重复遍历,最后导致内存超限。 - 快速幂的终止条件应该写为
n>0
,不然有些地方可能会卡住。