dsu on tree

好吧,这个毒瘤......

树剖和启发式合并的杂合体。

用于解决静态子树问题,复杂度O(nlogn * insert时间)

因为dsu是并查集的意思所以算法名字大概就是什么树上并查集之类的鬼东西。

因为dsu是并查集的意思所以函数名字看起来会很奇怪......

主要思想是这样的:

首先仿照树剖搞出轻重子节点。

dsu到一个点的时候,dsu所有的轻子树并消除影响。

dsu重子树并保留影响,从重子节点那里继承答案。

计算自己的贡献。

插入所有轻子树并更新自己的答案。

如果自己是轻子树的话,消除自己的影响。

回溯。

可知每个点最多经过logn个重链就能到达根,所以每个点最多插入logn次。


例题:

给你一棵树以1号节点为根的树,每个节点上有一个体积为v,价值为w的物品。现
在要你统计,对于所有点i,如果只能取子树i中的物品,则容积为m的背包

至多能装总价值多少的物品。 n <= 50000 m <= 300

跟大部分dsu on tree有点区别,因为是树形背包变种所以不用消除轻子树影响。

首先考虑正常背包:

计算完子节点后merge子节点和自己,复杂度V²

总共nV²会超时。

然后考虑dsu on tree:

把重儿子memcpy给自己,然后依次insert每个轻儿子,虽然看起来比之前那个慢但是实际上...

复杂度mnlogn,显得十分之快...

 #include <cstdio>
#include <algorithm>
#include <cstring>
const int N = , M = ;
struct Edge {
int v, nex;
}edge[N]; int t;
int e[N], son[N], siz[N];
int f[N][M], cost[N], val[N], V; inline void add(int x, int y) {
t++;
edge[t].v = y;
edge[t].nex = e[x];
e[x] = t;
return;
} void DFS_1(int x) {
siz[x] = ;
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
DFS_1(y);
siz[x] += siz[y];
if(siz[y] > siz[son[x]]) {
son[x] = y;
}
}
return;
} void insert(int x, int p) {
for(int i = V; i >= cost[x]; i--) {
f[p][i] = std::max(f[p][i], f[p][i - cost[x]] + val[x]);
}
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
insert(y, p);
}
return;
} void dsu(int x) {
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y == son[x]) {
continue;
}
dsu(y);
}
if(son[x]) {
dsu(son[x]);
memcpy(f[x], f[son[x]], sizeof(f[x]));
}
for(int i = V; i >= cost[x]; i--) {
f[x][i] = std::max(f[x][i], f[x][i - cost[x]] + val[x]);
}
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y == son[x]) {
continue;
}
insert(y, x);
}
return;
} int main() {
int n;
scanf("%d%d", &n, &V);
for(int i = ; i <= n; i++) {
scanf("%d%d", &cost[i], &val[i]);
}
for(int i = , x; i <= n; i++) {
scanf("%d", &x);
add(x, i);
}
DFS_1();
dsu();
for(int i = ; i <= n; i++) {
printf("%d ", f[i][V]);
}
return ;
}

AC代码


CF 600E Lomsat gelral

题意:求树上每个子树中出现次数最多的颜色。如果有相同次数就颜色相加。

套路:先走轻儿子,传清空标记。

然后走重儿子,不清空。继承答案。

统计自己的贡献。

insert轻儿子并统计答案。

如果有清空标记就清空。

 #include <cstdio>
const int N = ;
typedef long long LL;
struct Edge {
int v, nex;
}edge[N << ]; int top;
int e[N], val[N], bin[N], large[N], son[N], siz[N];
LL ans[N]; inline void add(int x, int y) {
top++;
edge[top].v = y;
edge[top].nex = e[x];
e[x] = top;
return;
} void DFS_1(int x, int f) {
siz[x] = ;
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y == f) {
continue;
}
DFS_1(y, x);
siz[x] += siz[y];
if(siz[y] > siz[son[x]]) {
son[x] = y;
}
}
return;
} void insert(int x, int f, int p) {
bin[val[x]]++;
if(bin[val[x]] > large[p]) {
large[p] = bin[val[x]];
ans[p] = val[x];
}
else if(bin[val[x]] == large[p]) {
ans[p] += val[x];
} for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y != f) {
insert(y, x, p);
}
}
return;
} void erase(int x, int f) {
bin[val[x]]--;
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y != f) {
erase(y, x);
}
}
return;
} void dsu(int x, int f, int k) {
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y == f || y == son[x]) {
continue;
}
dsu(y, x, );
}
if(son[x]) {
dsu(son[x], x, );
ans[x] = ans[son[x]];
large[x] = large[son[x]];
} bin[val[x]]++;
if(bin[val[x]] > large[x]) {
large[x] = bin[val[x]];
ans[x] = val[x];
}
else if(bin[val[x]] == large[x]) {
ans[x] += val[x];
} for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y == f || y == son[x]) {
continue;
}
insert(y, x, x);
}
if(!k) {
erase(x, f);
}
return;
} int main() {
int n;
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &val[i]);
}
for(int i = , x, y; i < n; i++) {
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);
}
DFS_1(, );
dsu(, , );
for(int i = ; i <= n; i++) {
printf("%I64d ", ans[i]);
}
return ;
}

AC代码

一开始WA了第25个点,没找出错来,仔细思考发现答案可能是n²级别的,爆int了,开long long之后A掉。

OSU! on tree的更多相关文章

  1. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  2. SAP CRM 树视图(TREE VIEW)

    树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...

  3. 无限分级和tree结构数据增删改【提供Demo下载】

    无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...

  4. 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...

  5. Leetcode 笔记 110 - Balanced Binary Tree

    题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...

  6. Leetcode 笔记 100 - Same Tree

    题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...

  7. Leetcode 笔记 99 - Recover Binary Search Tree

    题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...

  8. Leetcode 笔记 98 - Validate Binary Search Tree

    题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...

  9. Leetcode 笔记 101 - Symmetric Tree

    题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...

随机推荐

  1. 对象的使用处理,作用域的和ajax中this的理解

    首先,封装类,理解清楚你需要用的哪几个变量,然后声明,然后在类里封装函数,其中,constructor就是存放初始变量的地方. 这里还是datatable的处理解决, constructor(tabl ...

  2. ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)视图母版页教程 ASP.NET Core MVC (Razor)带有Section的视图母版页教程 ASP.NET Cor ...

  3. 推荐一款MongoDB的客户端管理工具--nosqlbooster

    今天给大家推荐一款MongoDB的客户端工具--nosqlbooster,这个也是我工作中一直使用的连接管理MongoDB的工具.这个工具还有个曾用名--mongobooster.nosqlboost ...

  4. Python变量之白首如新,倾盖如故

    python中的变量变量:将运算的中间结果暂存到内存中,方便后续程序调用.变量的命名规则:1.变量名由字母.数字.下划线组成.2.变量名可以用字母.下划线开头,但是不能以数字开头.3.变量名是区分大小 ...

  5. SQLServr添加数据列

    数据列定义 表中数据行的数据插入和数据类型都是基于数据列的,学会添加数据列在开发过程中是必不可少的. 使用SSMS数据库管理工具添加数据列 在数据表中添加一列或者多列步骤相同 1.连接数据库,选择数据 ...

  6. jenkins使用开始踩坑(1)

    上篇文章 安装教程 :https://www.cnblogs.com/linuxchao/p/linuxchao-jenkins-setup.html 一.前戏 话说上一篇文章安装完 JDK 和 je ...

  7. Extjs 解决grid分页bug问题

    //从后端获取数据加载到grid中var mainStore = new HeJsonStore({ url:'xxx', autoLoad:true, pageSize:20 }) //此方法最好放 ...

  8. 我的第一个python web开发框架(33)——接口代码重构

    前面ORM模块我们已经完成了开发,接下来要做的就是对项目代码进行重构了.因为对底层数据库操作模块(db_helper.py)进行了改造,之前项目的接口代码全都跑不起来了. 在写ORM模块时,我们已经对 ...

  9. django 静态文件的配置

    静态文件简介 一.准备文件 Jquery3.3.1文件,文件目录创建 二.创建过程如图 STATIC_URL = '/static/' #静态文件的别名 STATICFILES_DIRS=[ os.p ...

  10. Business Intelligence Tools We Recommend 1/4 – Metabase

    May 24, 2018 by Arturs Oganesyan-Peel BI is useful. It’s pretty. But it never really matters unless ...