题目
- 点分治
完成情况 | 题目 | 出处 |
---|---|---|
Tree | POJ 1741 | |
权限题 | Race | BZOJ 2599 [IOI2011] |
AC | 聪聪可可 | BZOJ 2152 |
AC | D Tree | HDU 4812 |
Amaz1ng Prime | CDOJ 1562 | |
采药人的路径 | BZOJ 3679 | |
Attack and Defence | Osipovsky Cup 2014 |
- Splay
完成情况 | 题目 | 出处 |
---|---|---|
AC | 普通平衡树 | BZOJ 3224 Tyvj 1728 |
AC | 宠物收养所 | BZOJ 1208 [HNOI2004] |
Book 书架 | BZOJ 1861 [ZJOI2006] | |
永无乡 | BZOJ 2733 [HNOI2012] | |
Army Formations | HDU 6133 | |
AC | 文艺平衡树 | BZOJ 3223 Tyvj 1729 |
Cards Sorting | Codeforces 830B (#424) |
点分治:
点分治通常是来解决那些在树上统计路径的问题,比如说统计有多少条长度为K的路径等等。如果用暴力,那么复杂度就是n2×g(n),其中g(n)是求lca的复杂度。那么哪怕用tarjan,这个总的复杂度也是n2的。这时候我们需要用到点分治。那么对于一棵树,我们先找到它的重心,然后再以重心为根,那么这时路径分为了两类,一类过重心,一类不过,我们只统计过重心的,然后不过重心的递归处理。由于我们是一棵子树一棵子树的处理,就可以用一个数据结构来维护答案,这个结构可以是线段树,平衡树,甚至是桶。这步只要做到nlogn及以下一般就可以。此时总的复杂度再在此基础上乘上logn。
例题:
- Tree(poj 1741):
很明显是点分治,我们先把到重心的距离排个序,此时就可以二分出来有多少条小于K,设有
- bzoj2599 [IOI2011]Race:(IOI的题哦~~~)
他只让你求一条路径,所以我们大可以用一个map,表示当边权和值为K时的最少条数是多少,是哪个点,这样子就可以只要遇到一个点,就看存不存在对应的点,然后更新答案。
- bzoj2152 聪聪可可:
大水题,就只用那个桶记一下。将
- hdu4812 D Tree:
注意这道题是点权。所以处理时不要忘了乘上重心的值。那么这道题我们扫到一个点N,其点权为
- CDOJ1562 Amaz1ng Prime:
我们这道题记一个桶,那么tong[i]=tong[1]×tong[i−1]+tong[2]×tong[i−2]+...+tong[i−1]×tong[1]。那么减去重合除以二后就是答案了。这是个卷积,就要用FFT。
- bzoj3697 采药人的路径:
首先,如果到这个点的路上有0点,并且这个点有匹配,那么就是可行的。所以,基于此,我们这样分类:如果到这点是
- Osipovsky Cup 2014 Kovrov, Sunday, December 21, 2014 Problem A.Attack and Defence / FJOI 2016 某道题
设左括号为
Splay:
(前几题都是基础,见我另一篇博客:传送门)
- bzoj2733 [HNOI2012]永无乡
这是明显的treap啊
这道题主要是如何合并两颗splay,我们可以模仿并查集的按大小合并,每次把小的移到大的上,这样子,做多logn次合并,所以总复杂度就是nlog2n。(平衡树本来的复杂度乘logn)
- hdu6133 Army Formations
一样的,启发式合并。注意加入一个点产生的贡献是(大于等于它的元素数量+1)×它本身的权值。所以我们可以把他加入根后把答案加上(右子树的权值的个数+该结点的cnt)×该结点的权值。然后暴力更新左子树。这样子看似复杂度高,实际上只有nlogn。
- 洛谷3372 【模板】线段树 1
类似线段树打标记。只不过我们在splay的时候,可以把它到root的点暴力拿出来,然后暴力的下放标记。
- Codeforces Round #424 (Div. 1, rated, based on VK Cup Finals) B.Cards Sorting
很简单,用一颗splay模拟,每次先将最小的找出来,splay到root,此时答案就是左子树的size,然后把左右子树互换。