树上数据结构

DFS序

LCT

树链剖分

点分治

树链剖分
漆子超《分治算法在树的路径问题中的应用》

  1. 一般是把所有的重链串在一起建线段树
  2. 如果只是需要求LCA,不需要建重链

可以求出一个序列,既是DFS序,又是轻重链的序列

P3178 [HAOI2015]树上操作

P2146 [NOI2015]软件包管理器

SP1487 PT07J - Query on a tree III

子树第 k 大

P2146 [NOI2015]软件包管理器

树链剖分 DFS序列

P3178 [HAOI2015]树上操作

树链剖分 DFS序列

P2486 [SDOI2011]染色

树链剖分 维护颜色段数

SP6779 GSS7 - Can you answer these queries VII

树上维护最大子段和

P1967 货车运输 / CF609E Minimum spanning tree for each edge

一个特殊的做法: 启发式合并 + 暴力
另一个特殊的做法: Kruskal合并时就回答两个集合询问的交集

P4180 [BJWC2010]严格次小生成树

上一题的基础上维护次小,就不能用投机取巧的方法了

P4374 [USACO18OPEN]Disruption P

离线,问子树内向外连边中权值最小是多少

P5423 [USACO19OPEN]Valleys P

并查集,维护有没有洞

P6572 [BalticOI 2017] Railway

虚树,树上差分

SP3197 TREECST - Tree Construction

删一条边,加一条边,最小化树的直径

P6277 [USACO20OPEN]Circus P

有趣的计数题

中心点:度数 >= 3的点

一个中心点,空2个的情况
(n - 2)! / (距离中心点的边数 <= 1的点的个数 - 2)!

一个中心点,空3个的情况
(n - 3)! / (距离中心点的边数 <= 2的点的个数 - 3)!

一个中心点,空k个的情况
(n - k)! / (距离中心点的边数 <= (k-1)的点的个数 - k)!

多个中心点的情况?

如果两个中心点之间的距离是d (之间有d条边)
那么当空位个数 >= d + 2的时候,两个中心点会合并

for (pair<int, int> j: b[n - 1 - i])
{
c[F(j.first)] += j.second;
}
for (int jj = 0; jj < b[n - 1 - i].size(); jj++)
{
pair<int, int> j: b[n - 1 - i][jj];
c[F(j.first)] += j.second;
}

map<string, double> g;

for (pair<string, double> i: g)
{
i.first // key, string
i.second // value, double
}

P2986 [USACO10MAR]Great Cow Gathering G

树的重心

P3629 [APIO2010]巡逻

树的直径

P4183 [USACO18JAN]Cow at Large P / P4186 [USACO18JAN]Cow at Large G

点分治

P3806 【模板】点分治1

点分治或者启发式合并

P6329 【模板】点分树 | 震波 题解

动态点分治

树上需要统计所有路径
2种思路

  1. 让每个路径在LCA的位置被统计到
  2. 点分治,让每个路径在重心的位置被统计到
set<int> s[10020];
void dfs(int x, int y, int d)
{
	// s[x] 表示子树x中所有节点的深度(从根节点开始算)的集合
	s[x].insert(d);
	for (pair<int, int> i: a[x])
	{
		if (i.first != y)
		{
			dfs(i.first, x);
			if (s[x].size() < s[i.first].size())
			{
				s[x].swap(s[i.first]);
			}
			枚举所有询问
			{
				if (这个询问已经被回答了)
				{
					continue;
				}
				for (int j: s[i.first])
				{
					if (s[x].find(询问的长度 + 2 * d - j) != s[x].end())
					{
						找到了
					}
				}
			}
			for (int j: s[i.first])
			{
				s[x].insert(j);
			}
		}
	}
}
可以在 n log n 的时间内回答一个询问
  1. 树上数据结构
    1. DFS序
    2. LCT
    3. 树链剖分
    4. 点分治
      1. P3178 [HAOI2015]树上操作
      2. P2146 [NOI2015]软件包管理器
      3. SP1487 PT07J - Query on a tree III
      4. P2146 [NOI2015]软件包管理器
      5. P3178 [HAOI2015]树上操作
      6. P2486 [SDOI2011]染色
      7. SP6779 GSS7 - Can you answer these queries VII
      8. P1967 货车运输 / CF609E Minimum spanning tree for each edge
      9. P4180 [BJWC2010]严格次小生成树
      10. P4374 [USACO18OPEN]Disruption P
      11. P5423 [USACO19OPEN]Valleys P
      12. P6572 [BalticOI 2017] Railway
      13. SP3197 TREECST - Tree Construction
      14. P6277 [USACO20OPEN]Circus P
      15. P2986 [USACO10MAR]Great Cow Gathering G
      16. P3629 [APIO2010]巡逻
      17. P4183 [USACO18JAN]Cow at Large P / P4186 [USACO18JAN]Cow at Large G
      18. P3806 【模板】点分治1
      19. P6329 【模板】点分树 | 震波 题解