传说中鱼只有7s的记忆。
而我不足7s的记忆。
真是悲伤TAT
记了什么东西,一会就忘记了。
我当时初中的时候想去自学高中课程……
但是自己完全没看懂。
其实不是自己看不懂而是自己“觉得”这个东西没什么用。
而且还”难”。
所以就选择性的忘记了。
我不想我学过的SAM,LCT什么的都变成选择性忘记的东西。
真的决定,要么一个东西完成100%.
要么就一点都不要碰。
在此总结一些OI上的容易”忘记”的知识点:
以下虽然有标号,但是感觉是不分先后的。
1.单调性
扫左端点右端点单调。
习题:
1.n个正整数,m个区间,选k个使得交区间的和最大。
注意到,按照左端点排好序之后,扫描左端点的时候,右端点是单调不降的。
实际上,右端点是右侧数第k个。
那么开个线段树随便做。
2.容斥原理
容斥原理似乎很容易解决一些问题:
1.交集转并集的补集。
大大走格子:
n*m的格子,有些点(1k)不能走,只能走右下,求方案数。
首先注意到任意走的话,可以写成组合数的形式。
那么我们容斥的话就要减掉所有的不合法的方案数。
注意到,如果第一个障碍不相同,那么其他就不相同了。
而只要踩了一个障碍,那么怎么走都不合法。
这样这个题就能解决了。
2.硬币购物(放个板子题)
3.HDU5731(插头DP+容斥)
3.分块思想
有一些东西,我们可以根号大暴力。
比如说51nod的三个题:
1.求整数n的不同划分方案数,一个划分中不能有相同的数字。
对n分类:>sqrt(n)只能选根号个,小于根号的也不会超过500。
f[i][j]表示凑i用了j个数字。
那么我们会发现实际上是在集合里填数的过程,即要么集合整体+1,要么加入一个新数再整体+1.
随便算。
2.求整数n的不同划分方案数,一个划分中可以有相同的数字。
对>sqrt(n)是可以用第一题的方法解决的,但是小于的话我们好像不太好解决。然而可以背包。
那么我们合并一下就完了。(注意大于的时候要设一个单位元)
3.你有n元钱。去买东西的时候,价格为i的恰有i个。正好花完这n元的方案数是多少?
如果>sqrt(n),那么我们就是依旧的第二题。
小于的话显然可以多重背包,但是会发现T掉了。(废话)
仔细看看就是个模意义下的前缀和?
解决了。。。
2016-11-21
Codeforces #380 div1.D
虽然注意到根号,但是完全不觉得有用,这就是死因所在。
我们一定要注意到奇特的地方,然后试图去解决它。
4.黑科技建图
我记得有个人的博客上写了这一坨东西,大概是一个可持久化线段树优化建图的事情,具体题目在BZOJ的某个题有个”XXXXXXII”这个题面应该很好找。
PA2011 Journey
首先我们发现暴力建图不可取。
然后如果想一想的话,实际上可以把这个连续的一段点拆成区间。
那么我们考虑用某个点P去更新答案的时候,只需要看P所在的这段区间是否被之前的子节点更新过了就行,因为这是bfs的过程。
我们发现每个区间必然只会更新一次,每个点必然也只会被更新一次。
那么总复杂度是
O
(跑得过)。
5.前缀和
不会前缀和的人在BJOI都被6题暴力了。
1.BJOI的SBD1T3。
2.n个数,问所有区间中多少个区间平均值>=m。
我们来看这个题。
首先显然的转前缀和,这样变成了s[r] - s[l - 1] >= len * m
不行,还不能做。
实际上,我们关于这个长度的定值,显然也是可前缀和的!
s[i] = s[i] - i * m;
这样的话我们就问有多少s[r] - s[l - 1] > 0。
离散化之后,枚举左端点,右端点在树状数组中查询。
6.离线算法
许多人啊。
他们不知道离线的可贵。
他们不知道只有删除的题可以离线转成只插入的题。
嗯没错我就是他们中的一员。
1.每次删除一条边,询问联通块个数。
离线+并查集。
2.莫队的题。
3.暴力分块重构。
4.覆盖问题(显然每个点只需要倒着覆盖一次即可)
……
7.倒着DP
习题1.奖励关。
习题2.hzwer的模拟赛有一个很好玩的题。
8.数值的定义域
这个是什么呢……
就是有个显然的把所有数值都存起来的题,然而我没想出来。
在做一些明显有最大值最小的东西,然而还让你变成最简分数的题的时候,可以看看它的数值的定义域,是不是可以承受的级别。
为什么要墨迹这么多呢,因为我记不得题面了。
9.最短路
我SPFA写拆点的题就没有一次能想到拆点啊摔
10.要学会解方程
这里的意思是,解一个方程的过程要写出来。
比如
你并不知道 a,b,c,d 是否是正整数,所以这样会很麻烦。
干脆写个高斯消元?
并不知道这种东西怎么考虑。
11.用堆维护删除序列
习题:链表+堆维护最大M子段和。
12.双指针
习题1:n只宠物小精灵一共有m种,你要每种至少抓一只,只能抓连续一段小精灵,求最小的区间长度。
注意这个转移指针是O(1)的。
//好像如果能用双指针转移往往都是O(1)的啊
//一般来讲前缀和+二分可以变成双指针的形式。
13.常见贪心:
用大的带小的:乘船问题什么的。
每次合并两个小的:合并果子。
balabala
14.暴力DP:
暴力DP的想法虽然大家都懂,就是先列一下朴素的方程,然后再说别的。
但是显然对于这个题……
真的是想一想暴力就A了啊GG
考虑f[i][j][k]表示sum为k,走到(i,j)。
然后没了。
15.CDQ分治:
作为一个能写动态开点线段树就懒得写别的的时候。
被卡空间的时候真是喜闻乐见。
神TM不会CDQ分治啊……
以后能用CDQ就不写数据结构了!
代码能力–;
=> 代码能力 < 0.
16.卡特兰数
卡特兰数f(n)是长度为2n合法括号序列方案数。
其计算公式
推导过程(ノ*・ω・)ノ
首先肯定是在 2m+1 位上 第一次出现了右括号(记作0).
对于剩下的 (n−m) 个1以及 (n−m−1) 个0所能任意组成的序列个数,等价于 (n−m) 个0以及 (n−m−1) 个1所能任意组成的序列个数.
那么实际上,对于所有的m,我们都计算一遍。
不过仔细想一想,实际上就是询问长度为 2n 序列中,有 n+1 个0的序列个数。
得证。
17.法里级数
我们如果要得到以m为分母的所有的真分数,那么肯定是:
(1..i) / m
但是肯定有一些东西不是最简分数。
我们知道,化简之后肯定是一个
p/q
的形式。
那么我们把它都化简之后,对于分母
q
能得到:
我们知道,对于所有化简之后的分母,我们能得到
m
个最简分数。这样,我们推断出一条性质:
估计这个很好玩,可以出题。
18.暴力建图的优化
河里有n个点,每个点上可以放m种盘子,每种盘子有代价。
现在问你在点上放盘子走到对岸的最小代价。
我们显然能看出这是个最短路题,但是我们暴力拆点建图的话,点数是
O(nm)
的,但是边数爆炸。
我们可以仔细考虑一下,实际上我们只需要对于点i的对应着第j个盘子向第j+1个盘子连代价差就行了。然后对于每个点,我们自己连自己的价格差就行,这样边数就降低到了
O(n2m)
.
19.删除一类问题的单调性/永久性
bzoj 3069 可以发现,每个边双在删除最后一条边的时候,才会被永久消除。我们倒过来插入,启发式合并即可。但是由于自己太懒了,写的LCT。
[PA2011]Journey 考虑到一个点如果被遍历到了,实际上它就被永久删除了,那么我们开个set什么的记录一下,或者用链表删掉它即可。
20.扫描线
扫描线和预处理不同,扫描线是你边加入贡献边算答案,你并不知道未来/历史的值,而预处理就是你知道过程中的所有的值。
我们来看SRM671的Div1600的题目:
给你一个序列s,问满足
a<b<c<d
且
ac=bd
的四元组个数。序列长度小于等于1000.
如果我们采取预处理的办法,是没办法得到答案的,因为我们要记录每一时刻的答案。那么不妨倒着枚举b,然后加入所有的(c,d)元组,再枚举a来更新答案。
dwn(i,n)
{
b = w[i];
rep(j,i - 1)cal(a = w[j],b);
c = w[i];
rep(j,i + 1,n)add(c,d = w[j]);
}
似乎四元组的常见思路是想办法枚举中间两个/把前两个和后两个独立开来。
询问[l,r]的数值个数。
[i,last[val[i]]]看作一个点,然后我们就需要知道横坐标在[l,r],纵坐标[0,l-1]的矩形点数。
这个显然可以1个log解决。
离线:扫描线
在线:可持久化
21.鸽巢原理
CF681A
构造题,题意:构造一个长度为n的序列,使得这m个区间的mex值的最小值最大。
做法:如果考虑鸽巢原理的话,我们每
1..len
就顺序放排列,这样的话显然的一件事情就是对于长度大于
len
的肯定能满足条件。这就是鸽巢原理的应用。
22.查询区间的小于一个数值的个数
这个显然是主席树/扫描线+树状数组。
题目:
一个n个节点的树,m次询问,每次询问一个点u满足dep[u] + val[u] >= dep[v]的v的个数。
显然对dfs序建树然后搞一搞就行了。
23.环<=>二分图(注意特殊的度数情况)
环=>入度等于出度。
那么意味着一个匹配。
BZOJ3171
直接建图跑费用流即可。
24.写递推式
无论什么时候,都不要忘记写递推式。
无论你觉得那个递推式难不难写。
收智商税的时候到了:
SRM664D1L1:
两堆石子。每次从大的里捞出小的那部分,然后放到小的石子那堆里。
问k次操作时候会变成啥样。(int范围)
交智商税的时间到了!
叫你不写递推!
叫你不写递推!
叫你不写递推!
叫你不写递推!
叫你不写递推!
叫你不写递推!
令
f[i]
表示第
i
次的最小的那堆的数目。
快速幂解决即可。
25.点分治
点分治是解决树上路径问题的比较常用的做法。
我们解决点分治的时候,如果处理要过x的路径,那么通常会面临算到了x的某个子树里面去这种问题。所以我们通用的一种做法是先计算答案,然后再Update一下这个子树的贡献。
还有一种想法是容斥,比如点分治的板子题,我们就用了容斥的思想,先什么都不管暴力算一算,不管在不在子树里面,然后直接把子树的这种暴力的答案减掉就行了。
26.树思想
之前自己只知道一棵叫做dfs/bfs树的东西。
现在知道了很多恐怖的东西。
比如点分树(solve(x)调用的时候形成的树),fail树(AC自动机的那个fail指针的树)。
很多东西需要自己发现,而不是别人说:”告诉你,点分治形成了个树”的时候,你才知道点分治会搞出个树。
27.线段树分治
我不得不说似乎这个东西挺妙的。
把插入删除变成只有插入和撤销两种操作,还是挺好玩的。
另外还学到了并查集的启发式合并,感觉非常开心。
28.欧拉定理
在
b>φ(p)
的前提下:
29.平方与卷积
(a−b)2=(b−a)2
.
那如果在前面乘上一个
f(a)
,就成卷积形式了,就可以FFT了!
30.斜率优化
其实是个很简单的东西,把
i
和
31.极差的性质:
一段区间的子区间极差最大值:
显然等于这段区间的极差。
因为增长区间之后,最大值不降最小值不增,故极差不降。
一段区间的子区间极差最小值:
显然等于每个相邻两个数的差值,理由是极差不降。
来自北京冬令营的T3。