令我兴奋不已,Philips Weng能回校给我们讲他在信息学上对一些专题上的见解和想法。
一早上,讲了三大部分:【线段树及其应用】、【树形DP】、【数论】。
【线段树及其应用】
首先,线段树发明之前,有一种叫做RMQ(Range Minimum Query)的问题,就是区间查询的问题。
- 给定一个长度为n的序列A,有Q个询问l,r,询问下标在区间[l,r]的A_i最小值。
- 可以使用经典的ST做法解决。
- 也可以离线后使用分治算法。
当然,这都是废话。
所谓线段树,就是动态RMQ问题,就是加上修改的RMQ问题。
- 单点修改,线段树修改时只会影响到log n个结点。
- 区间修改(懒惰标记),每次在需要修改的点那里打上一个lazy标记,在递归下去它的子树时下传标记,满足区间修改的目的。 Weng犇对下传标记的比喻:(老师让你做暑假作业,你是选择一开始就做完,还是选择要交的时候再做?☺)
引进一道例题:
给定有n个数的序列A,再给出Q个操作:
Change x y 把Ax改为y;
Query x y 询问max(A_i+…+A_j,x≤i≤j≤y){也就是询问[x..y]的最大子段和}
- 我们考虑用线段树做,一般可以线段树做的题都是可以合并的。我们想,子段和如何合并:
首先,两边的答案肯定要比较,现在考虑跨过mid点的子段:
然后从mid开始找左边的最大值,和右边的最大值,再用和与前面的进行比较,取出最大值,更新当前区间的答案。
用此思路,类推下去……
然后引进一个概念:二维线段树
二维线段树可以理解为“树套树”,其实就是嵌套线段树:在一棵线段树中,每一个区间都开一棵线段树,使得其可以实现许多线段树实现不了的东西。
其实二维线段树我不是很懂,我需要对这个概念加强一下认识……
还有一个更加重要的【区间第k大(小)】
最简单的就是“树套树”嘛,在一棵线段树的每个区间中,维护一棵权值线段树,很容易的去求这个区间的第k大(小)。但是,这个方法是很慢的时间复杂度为
O(nlog2)
。所以我们要再引进一种新的数据结构:
“可持久化线段树”也叫“主席树”,我不是很清楚,只知道它就是疯狂的复制自己的结点,然后就莫名其妙地求到了结果,望大神指教。
引进一道例题:
给定一长度为n的序列A,Q次询问,给定l,r,k,问A[l..r]的第k小值。n,Q≤100000
直接打个树套树我还是会的!!“主席树”我不会……
【树形DP】
- 树
- 无环且联通
- 确定根后存在明显的子结构(子树)
- 传递性,基本无后效性
- 根->叶子
- 叶子->根(较常见)
- 记忆化搜索/直接DP
- 常数优化->复杂度优化
一开始我还以为【树形DP】是三个当中最好理解的一个!
树形DP后面的很多概念和方法我都不太懂……
引进一道例题
给定一棵n个点的树,树上两点的距离定义为他们的最短路所经过的边的数量。问对于每个点i,其他点距离i最远是多少。
n≤100000
这题的解法有两个,第一个涉及到旋根操作,不懂,我就没法写了。第二种就简单一点:
求出这棵树的任意一条直径(u,v)
每个点的最远点必然是u或v,以u,v为根分别递归求出每个点到这两个点的距离,比较即可。
复杂度O(n)
树形DP最重要的,像DP最基础的一样:“树形背包”
- 给定一棵n个点的点带权的树,找出点数恰好为k的子联通图最大权值是多少。
1≤k≤n≤5000
我们设F[u][x]表示选了x个点,且u是其中的一个点的最大权值和。
F[u][i]=max(F[u][i],F[u][j]+F[son][i−j]);
两个程序,看起来差不多,但是时间复杂度从 O(n3) -> O(n2)
结束这一章时,Weng留下了一个非常难得难题:
真*树形背包
给定一棵n个点的树,每个点有重量c_i与价值v_i,要求选出一个子联通块,满足重量和不超过m,最大化价值和。
n,m≤1000.
【Basic Mathematics in OI】(数论)
- Modulo
定义:
设有两个整数a,b,满足:b≠0。
设a=q×b+r,其中0≤r<|b|
那么称a模b的值为r,记作a mod b=r。
若a mod b=c mod b,称a与c关于b同余,记作a≡c (mod b)
(这个很简单啦~)
性质:
以下,我们令a,b≥0 - a mod b=a- ⌊ab⌋ ×b
- (ka) mod (kb)=k*(a mod b)
为什么呢?
证明:
令a=rb+q, 0≤q<b,则ka=r(kb)+kq, 0≤kq<kb。
因此(ka) mod (kb)=kq=k×(a mod b)。
好理解不!我这个蒟蒻都理解了 - gcd(a,b) | (a mod b)
欧拉定理与模意义下逆元
(逆元)欧拉定理:
- 若gcd(a,b)=1,则
aφ(b)
≡1(mod b)
当b为质数时,
a(b−1)
≡1(mod b) (费马小定理)
- 模意义下逆元
若gcd(a,b)=1则存在r满足ar
≡
1 (mod b);
且r
≡
aφ(b)−1
(mod b),则称r为a在模意义下的逆元。
中国剩余定理
条件:
- 给定n组b_i,r_i,其中对于任意i≠j,gcd(b_i,b_j )=1。求出最小的自然数a,满足:
对于所有i,满足a≡r_i(mod b_i).
做法:
- 令M=∏b_i, M_i=M/b_i ,q_i=M_i在模b_i意义下的逆元,则:
a=(∑r_i M_i q_i) mod M.
Greatest Common Divisor(GCD)
- 辗转相除法….
- EX_GCD(扩展欧几里德算法)
给定a,b,c,求出一对整数x,y,满足ax+by=c,或判定不可能。
gcd(a,b) | ax+by
ax+by=gcd(a,b)
ax+by=gcd(a,b)=gcd(b,a mod b)=bx′+(a mod b)*y′ 迭代,O(logn)。
(这个比较简单~)
Combinatorics
(组合数)
- 令c(n,m)表示从n个物品中选出m个的方案数.
递推方程:c(n,m)=c(n−1,m−1)+c(n−1,m)
公式:
c(n,m)=n!m!(n−m)!
(归纳证明)
引进一道例题
挡板问题
将一排n个数分成m段,每段可以为空的方案数。
插入m−1个挡板