【BZOJ3252】攻略
题解:
首先贪心的会发现我们每次一定会选当前权值和最大的那个
然后在于怎么维护这个最大值
我们发现每个修改实际上是对沿途所有点的子树的修改
所以用线段树维护就可以了。。
另外注意有重复部分,但一定是包含关系所以比较好处理
代码:
#include <bits/stdc++.h>
using namespace std;
#define IL inline
#define ll long long
#define rint register ll
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define mid ((h+t)/2)
char ss[<<],*A=ss,*B=ss;
char gc()
{
return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
}
template<class T> void read(T &x)
{
rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=c^;
while (c=gc(),<c&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
const ll INF=1e9;
const ll N=3e5;
ll n,m,k,l,v[N],head[N],maxn[N],minn[N],sum[N],fa[N],cnt,ans;
struct re{
ll a,b;
}a[N];
const ll N2=N*;
ll data1[N2],data2[N2],data3[N2],lazy1[N2],lazy2[N2],real2[N2];
void arr(ll x,ll y)
{
a[++l].a=head[x];
a[l].b=y;
head[x]=l;
}
IL void down(ll x)
{
if (!lazy1[x]) return;
lazy1[x*]=lazy1[x*+]=lazy1[x];
lazy2[x*]+=lazy2[x];
lazy2[x*+]+=lazy2[x];
data3[x*]+=lazy2[x]; data3[x*+]+=lazy2[x];
data2[x*]=lazy1[x]; data2[x*+]=lazy1[x];
lazy1[x]=lazy2[x]=;
}
IL void updata(ll x)
{
if (data3[x*]<data3[x*+])
{
data2[x]=data2[x*+];
data1[x]=data1[x*+];
data3[x]=data3[x*+];
} else
{
data2[x]=data2[x*];
data1[x]=data1[x*];
data3[x]=data3[x*];
}
}
void build(ll x,ll h,ll t)
{
if (h==t)
{
data1[x]=real2[h]; return;
}
build(x*,h,mid); build(x*+,mid+,t);
}
void change(ll x,ll h,ll t,ll h1,ll t1,ll k1,ll k2)
{
if (h1<=h&&t<=t1)
{
lazy1[x]=k1; lazy2[x]+=k2; data3[x]+=k2; data2[x]=k1;
return;
}
down(x);
if (h1<=mid) change(x*,h,mid,h1,t1,k1,k2);
if (mid<t1) change(x*+,mid+,t,h1,t1,k1,k2);
updata(x);
}
void dfs1(ll x)
{
ll u=head[x];
if (!u)
{
real2[++cnt]=x;
return;
}
while (u)
{
ll vv=a[u].b;
dfs1(vv);
u=a[u].a;
}
}
void dfs(ll x,ll y)
{
ll u=head[x]; sum[x]=y+v[x];
if (!u)
{
minn[x]=maxn[x]=++cnt;
real2[cnt]=x;
change(,,n,cnt,cnt,,sum[x]);
return;
}
while (u)
{
ll vv=a[u].b;
dfs(vv,y+v[x]);
minn[x]=min(minn[x],minn[vv]);
maxn[x]=max(maxn[x],maxn[vv]);
u=a[u].a;
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
read(n); read(k);
rep(i,,n) read(v[i]);
rep(i,,n) minn[i]=INF;
rep(i,,n-)
{
ll x,y;
read(x); read(y); arr(x,y); fa[y]=x;
}
dfs1();
build(,,n); cnt=;
dfs(,);
rep(i,,k)
{
ll x=data1[],y=data2[],z=data3[];
ans+=z;
int kk1=minn[x]-,kk2=minn[x];
while (x!=y)
{
if (kk1>=minn[x]) change(,,n,minn[x],kk1,x,-(sum[x]-sum[y]));
if (kk2<=maxn[x]) change(,,n,kk2,maxn[x],x,-(sum[x]-sum[y]));
kk1=minn[x]-; kk2=maxn[x]+;
x=fa[x];
}
}
cout<<ans<<endl;
return ;
}
【BZOJ3252】攻略的更多相关文章
- [bzoj3252]攻略_dfs序_线段树_贪心
攻略 bzoj-3252 题目大意:给定一棵n个节点的有根树,点有点权.让你选出至多k个节点,使得他们到根的链的并最大. 注释:$1\le n\le 2\cdot 10^5$,$1\le val_i\ ...
- BZOJ3252: 攻略
Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏. 今天他得到了一款新游戏<XX半岛>,这款游戏有n个场景 ...
- BZOJ3252攻略——长链剖分+贪心
题目描述 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏<XX 半岛>,这款游戏有n个场景(scene),某 ...
- BZOJ3252 攻略 [树链剖分]
题目传送门 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1169 Solved: 554[Submit][Status][Discuss] ...
- bzoj3252 攻略 dfs序+线段树
题目传送门 题目大意:给出一棵树,1为根节点,每个节点都有权值,每个叶子节点都是一个游戏的结局,选择k个游戏结局,使得权值总和最大,同一个节点不会被重复计算. 思路:这道题最关键的是要想到一个性质,就 ...
- bzoj3252攻略(线段树+dfs序)
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 562 Solved: 238[Submit][Status][Discuss] D ...
- BZOJ3252 攻略(贪心+dfs序+线段树)
考虑贪心,每次选价值最大的链.选完之后对于链上点dfs序暴力修改子树.因为每个点最多被选一次,复杂度非常正确. #include<iostream> #include<cstdio& ...
- BZOJ3252: 攻略 可并堆
网上有很多人说用dfs序+线段树做...其实stl的堆可以...可并堆可以...很多奇奇怪怪的东西都能做... 可并堆比较好想...也比较好写... 分析: 首先,这是一个网络流做不了的题...数据太 ...
- BZOJ3252 攻略 贪心、长链剖分
传送门 给树竟直接给父子关系!!!真良心 首先一个贪心策略:每一次选择的链一定是所有链中权值最大的.这应该比较显然 那么我们接下来考虑如何维护这个贪心.我们可以使用长链剖分进行维护,对权值进行长链剖分 ...
- bzoj3252: 攻略(贪心)
/* 因为权值都是正的, 所以贪心的正确性能保证 然后重链贪心跑一下就好了 */ #include<cstdio> #include<algorithm> #include&l ...
随机推荐
- 题解-Atcoder_agc005D ~K Perm Counting
Problem AtCoder-agc005D 题意概要:给出\(n,k\),求合法的排列个数,其中合法定义为任何数字所在位置与自身值差的绝对值不为\(k\)(即求排列\(\{A_i\}\),使得\( ...
- 微信小程序采坑(一)
1.微信小程序如何让text内容空格 <text decode="{{true}}" space="{{true}}"> </text> ...
- C# 对话框使用整理
1.保存文件对话框 SaveFileDialog saveFile = new SaveFileDialog(); saveFile.Title = "save file"; sa ...
- postman 设置api_token,测试数据等操作
在postman的环境变量中先设置好一个用户的token(事先你的数据库里面要有用户的这个数据),如下图: 然后在api请求的url 的head头部添加对应的token键名,value值用花括号{{t ...
- js实现两种排序算法——冒泡、快速排序
* 一:冒牌排序1思想:冒泡排序思想:每一次对比相邻两个数据的大小,小的排在前面,如果前面的数据比后面的大就交换这两个数的位置要实现上述规则需要用到两层for循环,外层从第一个数到倒数第二个数,内层从 ...
- vue v-show绑定
在Vue中使用v-show指令来选择性的显示内容.它的属性值可以是布尔值.属性名称以及函数名称.如果使用函数来控制的话,无论函数内容如何运算判断,最终返回布尔值true或者false就可以了 < ...
- Modbus库开发笔记之十一:关于Modbus协议栈开发的说明
对于Modbus协议栈的整个开发内容,前面已经说得很清楚了,接下来我们说明一下与开发没有直接关系的内容. 首先,关于我为什么开发这个协议栈的问题.我们的初衷只是想能够在开发产品时不用每次都重写这一部分 ...
- JavaScript从入门到精通(附光盘1张):作者:明日科技出版社:清华大学出版社出版时间:2012年09月
本书介绍 一:本书 pdf 获取信息 本书下载:请申请加入本群 (QQ群:668345923), 并联系群主. 本群主有:本书pdf 全文教材 及附带的 光盘内容 二:本书目录介绍 第1篇 基 ...
- 第一次Java测试及感触
周四进行了java测试,感触很深,测试的题目是用Java实现一个ATM机的管理系统.最后3个小时后,我没有完成这次测试,但是我找到了自己的很多不足,明确了自己的问题究竟在哪里. 关于这次测试我不会的最 ...
- embed标签详解
HTML-embed标签详解 Embed(一).基本语法:embed src=url说明:embed可以用来插入各种多媒体,格式可以是 Midi.Wav.AIFF.AU.MP3等等, Net ...