收获
一. K极值问题
CodeVS 1245 第一篇
CodeVS 1245 第二篇
Uva 11997
首先这类问题可能要求所有的前k小值,可能只求第k小值。
这类问题与单调性有关,对于无序的序列一般需要先排序。
我想到了三种方法:
**①依次求
②排序可能情况
③二分答案**
对于方法①“依次求”,每次在待定状态内的元素要尽可能少,可以通过某些性质来减少元素的个数。
通常的做法是构建多条元素的单调序列,满足先选完前一个再选后一个。
这种做法可以扩展到多维。
对于方法②“排序可能情况”,待定情况要尽可能的少,这要通过某些性质来排除一些不可能的情况。
例如【Codevs1245】只限定在
i×j≤n
内求,最后弄出了调和级数的情况数级别
O(nlogn)
。
对于方法③,就是二分答案m,找比m小的个数。
方法①,方法②处理范围较小,询问较多的问题;
方法③处理范围较大,询问较少的问题。
再者如果是n个元素进行一系列操作组合而成的第k小。
考虑能否递推:先求出前2个的第k小,然后将这第k小与第3个求第k小。
二. 问题的种类
问题可以大致分为:
- 最优性问题
- 计数问题
- 判定性问题
- 计算问题
- 构造性问题
不同类的问题间是可以转化的。
常见的就是二分答案,将最优性问题转为计数问题或判定性问题。
这也有利于之后知识和方法的归纳。
三. 在线算法与离线算法
首先,在线算法和离线算法都是解决多个操作的问题的方法。
一个操作的就分不了什么在线离线了。
在我目前的理解中,在线算法就是强制维护,每解决完一个操作就再进行下一个操作;离线算法就是把所有操作给存下来,用某些方法,到最后依然能完成任务。
涉及修改操作的一般都使用在线算法。
除了在线莫队;或者强制在线中存在漏洞,使用逆向回代法。
离线算法,通常是在遍历某一个东西的时候顺便解决询问。通常有定序 (排序,邻接表)和逆向回代法的技巧。
四. 区间问题
BZOJ 3339 第一篇
BZOJ 3339 第二篇
BZOJ 3339 第三篇
BZOJ 2038
BZOJ 1878
BZOJ 1012
区间问题一般都是多个询问,可能有修改,可能没有修改。
对区间
[l,r]
进行操作的时候,通常使用区间加法或者区间减法。
区间加法:ST表,线段树,块状链表,etc。
区间减法:可有三种转化
①
[1,r]−[1,l−1]
②
[l,n]−[r+1,n]
③
[1,n]−[1,l−1]−[r+1,n]
不同的转化有不同的效果。
如果对多个区间询问进行离线排序,通常有以下几种方法:
**①对l排序——单调性
②对r排序——单调性
③分块排序——莫队**
有时候排序不只一个关键字,排多个关键字也是可以的。
使用方法①②,只要能搞掂一个端点的改变对所有函数值变化的一般规律即可。通常可以快速变化的函数是具有单调性的,如【BZOJ 3339】的mex函数。
五. 平面图网络流
最短路的求解用于结构统一、利于编号的网络。
发现打代码时找编号比较麻烦。
一般来说,平面图网络流的每一块区域都是矩形的吧。
那就弄个函数id(i,j)表示第i行,第j列的那个区域的编号。
然后注意边权与区域的关系。
特别注意小数据的特判:区域连边时,若只有1行,那么会出现s连到t的情况。
六. 思考问题时的几个策略
当设计出一个算法,且想不到更好的注意时,要想想自己没有利用哪些题目的特殊性,从特殊性进行方法的调整。
可以先想一下暴力算法,再从数据结构、算法优化等各种角度加以优化。
这样不仅是一种好的方法,而且也有一个程序来对拍。
在尝试求解的过程中,很可能会遭到失败。这时候不要全盘否定,要学会调整,增加几个变量。
七. 计数问题
计数问题,入手的角度通常有两个:组合数学,动态规划。
当然还有一些特殊的模型,如用基尔霍夫矩阵行列式进行生成树计数。
对于从动态规划入手的问题,有一个常见的技巧。
①首先算出小数据的答案,然后求解递推式;
②能这样干的特征通常是:输入数据少;
③递推式通常我们猜想是线性的,有时可能也会涉及到
n2
这种恶心的东西;
④设元时不要遗漏常数项;
⑤知道能设元的个数
p
;
⑥求值的会特别的讨厌,在这时候有两种方法:
- 方法1:打个暴力的代码
- 方法2:手算
求解递推式的过程同样讨厌,一样的有以上两种方法。
然而像【BZOJ 1002】这样的都涉及到高斯消元的,打个程序的性价比就会比较高了。
八. 动态规划与递推
其实是有区别的。
目前的理解:
递推求解的是计数问题和判定性问题;
动态规划求解的是最优性问题;
求
九. 树分块
就只会树分块的方法……
每块分在
n√
与
3n√
之间。
十. 树上莫队
【注意点1】在把树的路径转到线段上时,通过分类讨论两条线段的位置情况能更好地找到对应区间。
【注意点2】考虑LCA:包含情况不用考虑LCA,相交情况要考虑LCA。
【注意点3】特别注意莫队算法用于排序的重载运算符”<”的写法,很容易写错。
十一. Polya计数
十二. 乘法逆元
十三. 参数搜索——最优性问题的特殊解法
NOIP模拟题 最大公约数
枚举答案将最优性问题转为判定性问题。
若满足判定结果的单调性,可以二分。
十四. 并查集
CodeVS 1073
CodeVS 2597
NOIP模拟题连通
NOI 2001食物链
NOI 2002 银河英雄传说
BZOJ 1015星球大战
并查集解决的是连通性问题,可以进行合并、查询集合关系。
关系并查集:
①首先要找到所有不同的关系数,注意x到y和y到x是否相同。
②每种状态设个数,列表找出连续合并的基本运算规律。
③根据题目需要,找出其他的运算规律,常见的有同根判断关系是否正确、不同根的合并,通过连结虚拟知权值的边,算两次求解。
并查集维护前缀和:并查集可以将序列用链划分,同一条链上可以用区间减法求区间和。
十五. 弦图
题目:BZOJ 1006
会求完美消除序列就好了。
十六. 斜率优化与凸包
题目:BZOJ 1007,BZOJ 1010
要彻底理解斜率优化啊。
十七. 近似估算
①特征:“结果的相对误差不超过5%”之类的话,再给个SPJ;
②原则:能精确尽可能精确;
③对于不超时的精确部分,就让它保留,对于会超时的精确部分,才考虑估算;
④在用递推的方法时,对于小数据可以先暴力求,对于大数据再估算;
⑤估算的一种常见方法:取平均数、中位数、众数之类的。
十八. 求LCQ
①后缀数据结构
②Hash
十九. 最小生成树
BZOJ 1016
方法:Prim,Kruskal
性质:
①每种权值相同的边的数量是一定的
②权值相同的边对最小生成树的效果相同
计划
这个寒假还有好多作业……
BZOJ目前已经切了前16道,这个假期切完前25道就好了……
下学期要把学校的题都完成,也把BZOJ第一版做得差不多了。
关键还是要打好基础,把学校的学习认真完成。