【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序+线段树了.而对于第二个操作,考虑再维护一 ...
随机推荐
- 从程序猿到SAP产品经理,我是如何转型的?
文章作者:Jason Xia(夏建军) Jerry: 今天的文章来自Jason Xia, 我的老同事,和我一样从2007年进入SAP成都研究院工作至今.这篇文章讲述了Jason是如何从一名SAP资深开 ...
- poi实现Excel输出
/** * 第一个demo 导出Excel文件 * 第一行 第三个单元格中 写入 zhangsan */ @Test public void test1() throws IOException { ...
- drawRect - 谈画图功能的内存优化
作者介绍 作者:毕洪博 ( @毕洪博 ),iOS 开发者,pop Art 追随者.现在正在鼓捣 AVFoundation,博客 bihongbo.com, 欢迎大家找我讨论技术. 作者已将本文在微信公 ...
- iOS开发之MVVM在项目中的应用
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- Windows 10 建立wifi热点
如果当前是台式机那么需要一个usb的无线网卡,这里要注意如果你是使用台式机并且通过有线的方式上网,但是你的无线网卡适配器不能在禁用状态. 这里首先打开[运行]输入cmd,打开cmd(注意,这里要使用管 ...
- 单行代码实现xml转换成数组
$string = '<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_m ...
- linux centos 下ssh的连接
参考链接 虚拟机下CentOS7开启SSH连接 记录 我用finalssh连接virtualbox里的centos,发现报出java.net.UnknownHostException 一开始我以为是s ...
- C语言中的32个关键字
C语言中的32个关键字 数据类型关键字(12个) (1) char:声明字符型变量或函数 (2) double:声明双精度变量或函数 (3) enum:声明美剧类型 (4) ...
- 2-python基础
1.第一个程序 新建一个python文件,然后写上代码,运行即可 print("hello world") 2.变量 变量就是存东西,供后面来用的 变量名只能是 字母.数字或下划线 ...
- Java使用Apache的HttpClient组件发送https请求
如果我们直接通过普通的方式对https的链接发送请求,会报一个如下的错误: javax.net.ssl.SSLHandshakeException: sun.security.validator.Va ...