【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序+线段树了.而对于第二个操作,考虑再维护一 ...
随机推荐
- 【TensorFlow入门完全指南】神经网络篇·自动编码机
自动编码机(Autoencoder)属于非监督学习,不需要对训练样本进行标记.自动编码机(Autoencoder)由三层网络组成,其中输入层神经元数量与输出层神经元数量相等,中间层神经元数量少于输入层 ...
- CORS的原理及应用
CORS的原理及应用 CORS是跨站资源共享,同样是解决浏览器的同源策略 其本质是设置响应头,使得浏览器允许跨域请求. 第三方网站返回数据的时候在浏览器的响应头中添加允许的域名,允许所有的用* 1 简 ...
- jvm | 基于栈的解释器执行过程
一段简单的算术代码: public class Demo { public static void main(String[] args) { int a = 1; int b = 2; int c ...
- 中英文字符串截取函数msubstr
Thinkphp内置了一个可以媲美smarty的模板引擎,给我们带来了很大的方便.调用函数也一样,可以和smarty一样调用自己需要的函数,而官方也内置了一些常用的函数供大家调用. 比如今天我们说的截 ...
- ASP.NET 验证控件报错:WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping。
在Visual Studio 2012中添加并使用验证控件时,可能会遇到如下的错误: WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResour ...
- 作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)
作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)
- EXC_BAD_ACCESS调试
有时候,你会遇到由EXCBADACCESS造成崩溃. 这篇文件会告诉你什么是EXCBADACCESS,以及它产生的原因.我还会提供一些EXCBADACCESS错误的解决方案. 1. 什么是 EXCBA ...
- 利用SignalR实现实时聊天
2018/10/10:博主第一次写原创博文而且还是关于C#的(博主是从前端转过来的),菜鸟一枚,如果有什么写的不对,理解错误,还望各位轻喷.,从SignalR开始! 首先先介绍一下关于SignalR的 ...
- vuePress的使用
今天来玩一玩vuePress的使用,用markdown来编辑一个页面网站,这里谈论到了简单使用,细节可以去官网上去查看 开始安装 项目依赖 // package.json { "name&q ...
- vue-awesome-swiper插件爬坑
最近自己在做一个基于vue的知乎的移动端单页面,遇到很多坑,先说一下遇到最大的坑,其实并不推荐使用 vue-awesome-swiper,如果项目应用轮播,切换少的话.言归正传,现在来介绍vue-aw ...