OSU! on tree
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的更多相关文章
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- SAP CRM 树视图(TREE VIEW)
树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...
- 无限分级和tree结构数据增删改【提供Demo下载】
无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...
- 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 100 - Same Tree
题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
- Leetcode 笔记 101 - Symmetric Tree
题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...
随机推荐
- WPF开源项目
WPF有很多优秀的开源项目,我以为大家都知道,结果,问了很多人,其实他们不知道.唉,太可惜了! 先介绍两个比较牛逼的界面库 1.MaterialDesignInXamlToolkit Android风 ...
- SQL Server数据库————连接查询和分组查询
SQL Server数据库————连接查询和分组查询 分组查询 select 列from <表名> where …… group by 列 注意:跟order by一样group ...
- 浅谈TCP IP协议栈(二)IP地址
上一节大致了解TCP/IP协议栈是个啥东西,依旧是雾里看花的状态,有很多时候学一门新知识时,开头总是很急躁,无从下手,刚学会一点儿,却发现连点皮毛都不算,成就感太低,所以任何时候学习最重要的是要在合适 ...
- 【Intellij idea】spring中@Autowired注入失败
@Autowired注入失败失败的解决办法? 现有的解决的方案是: 打开file-settings或者ctrl+alt+s -> Editor 然后在Inspections 点击搜索栏 输入Sp ...
- Flex builder4.6激活【转】
方法一: 1.到Adobe官网下载FlashBuilder 4.6 http://download.adobe.com/pub/adobe/flex/win/FlashBuilder_4_6_LS10 ...
- javascript Json和String互转
var jsonText = "{\"id\":\"123\",\"name\":\"tom\",\&qu ...
- Jenkins+VS项目持续集成
软件安装 安装包下载连接:https://jenkins.io/download/ 安装步奏:略 账户名:admin 密码:C:\Program Files (x86)\Jenkins\secrets ...
- Python开发【socket篇】解决粘包
客户端 import os import json import struct import socket sk = socket.socket() sk.connect(('127.0.0.1',8 ...
- Python开发【前端篇】HTML
1.html概述和基本结构 html概述 HTML是 HyperText Mark-up Language 的首字母简写,意思是超文本标记语言,超文本指的是超链接,标记指的是标签,是一种用来制作网页的 ...
- hbase参数配置优化
因官方Book Performance Tuning部分章节没有按配置项进行索引,不能达到快速查阅的效果.所以我以配置项驱动,重新整理了原文,并补充一些自己的理解,如有错误,欢迎指正. 配置优化 zo ...