【bzoj3252】攻略 贪心+DFS序+线段树
题目描述
输入
输出
样例输入
5 2
4 3 2 1 1
1 2
1 5
2 3
2 4
样例输出
10
题解
贪心+DFS序+树状数组
首先有个显而易见的贪心策略:每次选能够获得最大价值的点。
于是我们只需要设法维护这个贪心即可。
考虑到一个点被使用,影响到的只有它的子树中的节点。所以我们可以按路径长度对DFS序上每个点建立线段树,并线段树维护DFS序上的区间最大值、区间最大值位置,支持修改操作。
所以我们每次操作拿出最大值加到答案中,并对于最大值位置对应的点,在它到根节点的路径上不断向上移动,每到一个点就更新它的子树,把它们的价值减去这个点的权值。直到移动到某个已经被使用了的点停止。(因为如果一个点被使用,则它的祖先节点也一定均被使用)。
时间复杂度为$O((n+k)\log n)$。
#include <cstdio>
#include <algorithm>
#define N 200010
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
using namespace std;
typedef long long ll;
int fa[N] , head[N] , to[N] , next[N] , cnt , pos[N] , ref[N] , last[N] , tot , mp[N << 2] , del[N];
ll w[N] , v[N] , mx[N << 2] , tag[N << 2];
void add(int x , int y)
{
to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
}
void dfs(int x)
{
int i;
v[x] = v[fa[x]] + w[x] , pos[x] = ++tot , ref[tot] = x;
for(i = head[x] ; i ; i = next[i]) dfs(to[i]);
last[x] = tot;
}
void pushup(int x)
{
int l = x << 1 , r = x << 1 | 1;
if(mx[l] > mx[r]) mx[x] = mx[l] , mp[x] = mp[l];
else mx[x] = mx[r] , mp[x] = mp[r];
}
void pushdown(int x)
{
if(tag[x])
{
int l = x << 1 , r = x << 1 | 1;
mx[l] -= tag[x] , mx[r] -= tag[x];
tag[l] += tag[x] , tag[r] += tag[x];
tag[x] = 0;
}
}
void build(int l , int r , int x)
{
if(l == r)
{
mx[x] = v[ref[l]] , mp[x] = l;
return;
}
int mid = (l + r) >> 1;
build(lson) , build(rson);
pushup(x);
}
void update(int b , int e , ll a , int l , int r , int x)
{
if(b <= l && r <= e)
{
mx[x] -= a , tag[x] += a;
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if(b <= mid) update(b , e , a , lson);
if(e > mid) update(b , e , a , rson);
pushup(x);
}
int main()
{
int n , k , i , x , y;
ll ans = 0;
scanf("%d%d" , &n , &k);
for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &w[i]);
for(i = 1 ; i < n ; i ++ ) scanf("%d%d" , &x , &y) , fa[y] = x , add(x , y);
dfs(1);
build(1 , n , 1);
while(k -- )
{
ans += mx[1] , x = ref[mp[1]];
while(x && !del[x]) update(pos[x] , last[x] , w[x] , 1 , n , 1) , del[x] = 1 , x = fa[x];
}
printf("%lld\n" , ans);
return 0;
}
【bzoj3252】攻略 贪心+DFS序+线段树的更多相关文章
- bzoj3252 攻略 贪心+dfs序+线段树
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3252 题解 有一个非常显然的贪心思路:每次选择目前走到那儿能够获得的新权值最大的点. 证明的话 ...
- [Bzoj3252]攻略(dfs序+线段树)
Description 题目链接 Solution 可以想到,每次肯定是拿最大价值为最优 考虑改变树上一个点的值,只会影响它的子树,也就是dfs序上的一个区间, 于是可以以dfs序建线段树,这样就变成 ...
- BZOJ 3252题解(贪心+dfs序+线段树)
题面 传送门 分析 此题做法很多,树形DP,DFS序+线段树,树链剖分都可以做 这里给出DFS序+线段树的代码 我们用线段树维护到根节点路径上节点权值之和的最大值,以及取到最大值的节点编号x 每次从根 ...
- BZOJ3252 攻略(贪心+dfs序+线段树)
考虑贪心,每次选价值最大的链.选完之后对于链上点dfs序暴力修改子树.因为每个点最多被选一次,复杂度非常正确. #include<iostream> #include<cstdio& ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树
题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...
- Codeforces Round #442 (Div. 2)A,B,C,D,E(STL,dp,贪心,bfs,dfs序+线段树)
A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
随机推荐
- 这些O2O比你们更靠谱儿
本文纯属虚构,如有雷同,全是 C2C(Copy to China). 一 「什么社区 O2O,不就是跑腿儿的?那叮*小区不好好跑腿儿,非要搞什么狗屁社交,不是死了?」 三十四岁的老刘咽了口唾沫,接着跟 ...
- echarts实现仪表盘(自己动起来,没有后端,顺便重温math.random
let a = parseInt(Math.random() * (2 + 1), 10); let arr = []; arr.push(res[a]); let option = { toolti ...
- ubuntu 16.04 +anaconda3.6 +Nvidia DRIVER 390.77 +CUDA9.0 +cudnn7.0.4+tensorflow1.5.0+neural-style
这是我第一个人工智能实验.虽然原理不是很懂,但是觉得深度学习真的很有趣.教程如下. Table of Contents 配置 时间轴 前期准备工作 anaconda3 安装 bug 1:conda:未 ...
- 【线段树合并】bzoj3545: [ONTAK2010]Peaks
1A还行 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问, ...
- Linux菜鸟起飞之路【六】权限管理(二)
一.权限信息详解 ls -l 文件 //查看文件权限写法1 ll 文件 //查看文件权限写法2 ls -dl 目录 //查看目录权限写法1 ll -d 目录 //查看目录权限写法2 文件权限格式: ...
- 传智 Python基础班+就业班+课件 【最新完整无加密视频课程】
点击了解更多Python课程>>> 传智 Python基础班+就业班+课件 [最新完整无加密视频课程] 直接课程目录 python基础 linux操作系统基础) 1-Linux以及命 ...
- W3CPLUS DEMO一些有意思的效果备份
时间轴轮播图: http://www.w3cplus.com/w3cplusDemo/demos/timeline.html css3各种图标效果: http://www.w3cplus.com/w3 ...
- Ubuntu 16.04系统安装步骤
1.安装系统 2.设置更新源,自动检测最优更新源 3.关闭自动更新 4.设置终端样式 5.设置终端快捷键 6.安装vim,配置.vimrc 7.修改.bashrc第62行,小写w为大写W,设置终端不显 ...
- Linux异常体系之vector_stub宏解析
ARM-Linux汇编的宏定义语法说明如下: 使用注意: 1.宏定义以.macro开始,以.endm结束 2.可带参数,参数可有默认值 3.直接使用参数的名字\arg vector_stub宏的功能: ...
- cento命令之which、whereis、locate、find
[which] 查看可执行文件的位置 语法: [root@localhost ~]# which 可执行文件名称 例如: [root@localhost ~]# which passwd /usr/b ...