Day1
权值线段树相关。不同于普通线段树在位置上维护值等信息,权值线段树相当于在数轴上维护数的次数信息。
通常需要配合离散化和动态开点等技巧。
离散化
可以使用STL
里的set
或者map
。也可以使用unique
。unique
的使用方法类似sort
,返回一个指针,即去重后最后一个数的指针。可以用unique(b,b+n)-b
得到不重数字数量。注意传入的必须是有序序列,通常先sort
一遍。
动态开点
strct node{
int l,r,w,f;
}
void sum(int &k,int l,int r,int ll,int rr)
{
if(!k)k=++c;
……………
sum(e[k].l,l,mid,ll,rr);
sum(e[k].r,r,mid+1,ll,rr);
}
函数传入的l
和r
为此点的区间范围,这样传入可以节省内存。ll
和rr
为通常线段树中也有的操作范围。传入&k
是动态开点的精髓。
另外打了数链剖分(实际上我Day2才打)和主席树的模板,之后应该会添加到模板库里。
Problem List
CF915E Physical Education Lessons
紫CF558E A Simple Task
紫P3834 【模板】可持久化线段树 1(主席树)
紫CF960F Pathwalks
紫CF1111C Creative Snap
紫
Day2
早上学Splay
,我听了一半(其实完全没听,FHQ YES!)。
下午就面向代码编程打了个Lint Cut Tree
。
Problem List
P2286 [HNOI2004]宠物收养场
紫P3384 【模板】重链剖分
蓝P4779 【模板】单源最短路径(标准版)
黄P3372 【模板】线段树 1
黄P3690 【模板】Link Cut Tree (动态树)
紫
Day3
正常的dp,区间dp、状压dp、树上dp。
区间dp
区间dp的基本做法就是枚举长度然后枚举区间,有时需要枚举断点。从小的区间扩展到大的区间。
for k
for l
for x
状压dp
状压dp就是把一些状态信息压缩到数字中,就可以比较方便地表示局面,用数组或者map
什么的记录一下。需要熟练二进制操作。
树上dp
把儿子的信息上传到父亲节点。不管上面来的或者下面上来的全部都在这里处理。
Problem List
P2234 [HNOI2002]营业额统计
蓝P1220 关路灯
蓝P3205 [HNOI2010]合唱队
蓝P1896 [SCOI2005]互不侵犯
蓝P4302 [SCOI2003]字符串折叠
紫P1122 最大子树和
绿P2051 [AHOI2009]中国象棋
紫
Day4
今天就是搜索。
启发式搜索
就是人来启发计算机2333(教育感化挽救
迭代加深搜索
对于一些搜索没有界限的用。从小到大枚举答案深度。题目中可能会有最大深度限制。
void dfs(int deep)
{
if(!deep)
{
return;
}
dfs(deep-1);
}
for(int i=0;;i++)dfs(i);
IDA*
估值函数h()
估计一下现状距离答案的距离。
如果h()
是严格下界,那么就可以将一些不可能在预定期望得到答案(可以结合迭代加深)的给break
掉。也可以使用h()
将一层中的子问题进行排序。
Problem List
UVA12558 埃及分数 Egyptian Fractions (HARD version)
蓝P5507 机关
蓝P2534 [AHOI2012]铁盘整理
紫
Day5
组合数
$C{^m_n}=C{^{n-m}_{n}}$
$C{^m_n}=C{^{k-1}{n-1}}+C{^k{n-1}}$ 这一条可以结合杨辉三角
$ {k \over n}C{^m_n}=C{^{m-1}_{n-1}}$
$C^0_n + C^1_n + C^2_n +{\cdot \cdot \cdot}+ C^n_n = 2^n$
捆绑法、插空法、隔板法
树上倍增
基环外向树dp
一棵树,再连其中两个点,就成为了一个基环树。
最小生成树
DFS序
按照DFS顺序进行编号,可以把树上信息搞到链上方便维护。
欧拉序
按照DFS序遍历,但是回溯的时候也加入序列。
可以将LCA转换为RMQ问题。