
分治
Bahuia
软件工程博士
展开
-
HDU 5977 树的点分治 + 状态压缩 + 枚举子集
题意:给一棵节点数为n,节点种类为k的无根树,问其中有多少种不同的简单路径,可以满足路径上经过所有k种类型的点?(a->b与b->a算作两条路径,起点与终点也可以相同)思路:现场赛的时候k的大小是7,当时看到这题也没多想就树形dp水过了。现在重现赛k改成了10,这时候用树形dp,无论是时间还是空间复杂度都很爆炸。后来听说这题的正解是树分治,于是就学习了一波,然后重新来做这道题,关于原创 2016-11-07 20:09:10 · 2464 阅读 · 0 评论 -
HDU 5896 CDQ分治+NTT
题意:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5829 求n个点能构成的有环图的数目。思路:母题是HDU 5552:http://blog.youkuaiyun.com/Bahuia/article/details/78109301 两题思路一致,只是改变了所求结果,推导发生变化。代码:#include <bits/stdc++.h>using nam原创 2017-09-27 09:34:01 · 609 阅读 · 0 评论 -
HDU 5552 CDQ分治+NTT
题意:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5829 统计n个点可以组成多少种不同的有环连通图,其中每条边可以染成m种颜色。思路:分别统计f(n)为n个点的连通图数目,g(n)为n个点能构成的图数目,h(n)为n个点能构成的树的数目,然后递推出公式,发现是个卷积形式,可以用FFT加速,这里会爆精度,改用NTT。代码:#include <bit原创 2017-09-27 09:30:07 · 926 阅读 · 0 评论 -
HDU - 5730 CDQ分治 + FFT
题意:有一串长度为n的序列,可以任意划分,题目给出长度从1到n的块的价值,每一种划分的价值等于划分出来的所有块的价值的乘积,问所有划分方法得到的价值的总和是多少?思路:这题很容易就能得到状态转移方程,设dp[i]是长度为i的序列的价值总和,那么就有状态转移方程:然而计算这样的状态转移需要花费O(n^2)的时间,不能满足要求。注意观察到这是一个离散卷积形式,可以用FFT来加速原创 2017-03-21 14:15:31 · 521 阅读 · 0 评论 -
HDU - 1166 CDQ分治
题意:树状数组的入门题,单点修改,区间求和。思路:这题是最基础的BIT,也可以用cdq分治来做。简单地介绍一下cdq分治。cdq分治是一种特殊的分治法,只能支持离线操作,往往可以替代复杂的数据结构,而且具有常数较小的优点。cdq分治的基本思想:1. 对于一段序列[L,R);2. 将其从中间分成两个部分[L,M),[M.R),并递归处理子问题。3. 归并时要考虑左半部原创 2017-02-07 14:49:59 · 471 阅读 · 0 评论 -
HDU - 5690 分治 + 快速幂思想
题意:判断数位长度为m且每一位上的数字都是x的数模k的结果是否等于c。思路:也可以算是一种分治吧,把大的整数按数位折半考虑,类似于快速幂的处理方式,如果是偶数,前一半和后一半的结果相同,不需要重复处理,如果是奇数,合并的时候加上中间的x即可。代码:#include using namespace std;typedef long long ll;ll pow_mod(l原创 2017-02-06 10:24:41 · 422 阅读 · 0 评论 -
POJ - 1987 树分治
题意:与POJ-1741一致,传送门:点击打开链接思路:没什么意思,直接套模板。代码:#include #include #include #include #include using namespace std;typedef long long ll;const int MAXN = 1e5 + 10;struct node { int v;原创 2017-02-06 09:51:02 · 360 阅读 · 0 评论 -
POJ 1741 树的点分治
对于树上的路径问题,一种高效的处理方式就是分治算法。关于树分治算法的研究,详见2009年IOI国家集训队论文——《分治算法在树的路径问题中的应用》。 通常对于树上的分治算法有两种,第一种是针对点进行的分治,另一种是针对边进行的分治,可以证明,大部分情况下点分治算法的性能更加稳定,而边分治在某些情况下,算法效率非常低。所以以下主要讨论点分治。 如POJ-1741,求解一棵树中路径原创 2016-11-07 15:00:41 · 1023 阅读 · 0 评论 -
POJ - 3714 分治
题意:给出两个集合,每个集合中有n个点,求属于不同集合的两个点之间的最短距离。思路:分治,套用最接近点对问题的方法,只要在保存res的时候判断是否是属于同一个集合即可。代码:#include #include #include #include using namespace std;typedef long long ll;const int MAXN = 2e5原创 2017-02-06 09:07:21 · 1302 阅读 · 1 评论 -
HDU - 1007 分治(最接近点对模板)
题意:求出平面上n个点中最接近的两个点的距离。思路:最接近点对问题,利用分治法解决,先按照x排序,进行分治,并对每段区间内的点再按照y排序,可以证明每段区间内的比较次数为常数,复杂度为O(nlogn)。代码:#include using namespace std;const int MAXN = 1e5 + 10;struct node { double x,原创 2017-02-05 20:01:39 · 409 阅读 · 0 评论 -
51Nod - 1674 分治
题意:lyk拥有一个区间。它规定一个区间的价值为这个区间中所有数and起来的值与这个区间所有数or起来的值的乘积。例如3个数2,3,6。它们and起来的值为2,or起来的值为7,这个区间对答案的贡献为2*7=14。现在lyk有一个n个数的序列,它想知道所有n*(n+1)/2个区间的贡献的和对1000000007取模后的结果是多少。例如当这个序列为{3,4,5原创 2017-02-05 18:53:09 · 451 阅读 · 0 评论 -
HDU 5618 CDQ分治(三维偏序)
题意:题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5618 给出n个有序对(a,,b,c),对于每个(ai,bi,ci)找到满足aj <=ai,bj<=bi,cj<=ci的有序对有多少个。思路:典型的三维偏序问题,可以用CDQ分治来解决。 首先将有序对按照a的大小排序,这样对区间[L,R)进行分治的时候就可以默认左半部分[L,M)的a原创 2017-10-06 22:49:13 · 666 阅读 · 0 评论