“总感觉定期重构和分块……..跟骗分似的,都是在中和暴力的时空复杂度。。”——Goes && G.S.M.
【没错,这俩是一个人,就是我,啧。】
“算法上的事能叫暴力么,重构不能叫暴力”——doge233
【啧,他,是一个秘密。(坏笑脸)】
分块和定期重构
都是在查询的时候,对完整块 或者 已知部分直接查询,
对不完整的块 或者 修改后未知的 进行暴力查询。
于是机智的我把二者放在了一起,
当作一种“思想”来学。
(我觉得….当思想学吧….并不喜欢算法…..啧)
刚学oi的时候什么都不懂,大概是听过一句话
“你这就相当于牺牲空间来保证时间么。”
于是我想,大概分块和定期重构的核心思想是:
时间复杂度和空间复杂度,互相牺牲自己,保证对方。
于是经常出现神奇的阈值,它的名字就叫——“根号n”。
以上为Goes对这两部分内容的一个统一理解。
下面就是一些…..我自己能看懂的对分块和定期重构的一些……
课堂笔记……?
【所以我就直接把我用编译器写的课堂笔记粘贴过来就好了】
#if 0
Note in class on 2017.12.22.
Beijing exercise for ten days
It's the eighth day.
Writers: G.S.M. && Goes .
The day's up.[今天是冬至]
#endif
#if 0
定期重构(思想):
对于一些修改和询问操作,
对一个修改操作我们只是记录下来,
等到记录的修改操作达到一定阈值时,
我们才真正进行修改。对每个询问,
在维护好的数组和未进行修改的分别进行询问
eg1. 二维平面上n个点,两种操作:
A:加入一个点 ; B: 询问Ax+By的最大值
方法一:动态凸包
显然可以构造凸包,动态维护即可(水平序?)
方法二:定期重构
凸包维护已知,暴力询问修改操作,
制定合理阈值,修改操作达到阈值时进行修改
eg2.带修改 树上K大:
给定一个n个点的森林,m个操作,
每次可以加一条边或删一条边或寻味一条链上
第K大的数,始终保证n个点为森林
【不会。
1.若果没有删除和添加操作,我们可以用主席树维护;
2.在未进行修改的情况下,拆链查询(树上原链+添加删除链)
3.每S个操作后,重构一遍主席树。(S为阈值,根号n就好)
#endif
#if 0
分块(思想):均衡效率
对于序列分块的基本方法:
通常将一类具有相同性质的数放进相同的块中。
一般来说,从序列的第一个元素开始,每连续的S个元素组成一个块。
若最终剩余的元素不足S个,将它们组成一个块。
莫队:学的时候都是按分块学的
(感觉....就是定期重构+分块吧2333)
树上分块:(糖果公园)
几个典型分块例题:(熟悉基础套路)
eg1.BZOJ 2002
给一个长度为n的序列{a},
表示i < ai <= n + 1。m个操作。
操作A:修改ai,满足上述条件;
操作B:询问从x=i开始每次讲x=ax直到x>n需要变换几次。
n <= 50000, m <= 50000。
eg2.BZOJ 3343
给一长度为n的数列ai。m个操作。
操作A:区间加;操作B:询问区间有多少个数大于C。
n <= 10^6, m <= 3000。
eg3.BZOJ 2724
给定n个数,每次询问区间[l, r]里面的众数。
出现次数相同要求权值最小。n <= 40000, m <= 50000
[分块+前缀和]
#endif
End main.