BZOJ 3252 攻略
题目简述:树版[k取方格数]
众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏。今天他得到了一款新游戏《XX
半岛》,这款游戏有n个场景(scene),某些场景可以通过不同的选择支到达其他场景。所有场景和选择支构成树状
结构:开始游戏时在根节点(共通线),叶子节点为结局。每个场景有一个价值,现在桂马开启攻略之神模式,同
时攻略k次该游戏,问他观赏到的场景的价值和最大是多少(同一场景观看多次是不能重复得到价值的)
“为什么你还没玩就知道每个场景的价值呢?”
“我已经看到结局了。”
Input
第一行两个正整数n,k
第二行n个正整数,表示每个场景的价值
以下n-1行,每行2个整数a,b,表示a场景有个选择支通向b场景(即a是b的父亲)
保证场景1为根节点
n<=200000,1<=场景价值<=2^31-1
Output
输出一个整数表示答案
Sample Input
5 2 4 3 2 1 1 1 2 1 5 2 3 2 4
Sample Output
10
思路: 贪心的去想,就是我们先取出权值最大的一条链,然后逐个更新链上的每个点的子树,更新完之后再取出最大的一条链,那么我们就需要一种快速的取最大值和id的方案,当然线段树,当然要配合dfs序,我们在更新的时候,如果更新到的这个节点已经被更新过了,那么就可以直接跳出了,因为每个节点最多只能被用一次。
思路2: 我们对于每一个节点,我把这个节点的权值给他的若干个孩子中的哪个孩子呢,当然我尽量的想给最大的那个孩子,然后我们可以对于每个一个节点维护一个可并堆,就可以直接把当前节点的权值给权值最大的孩子链,那么一路dfs回退,回退到根节点,堆顶的前k个元素就是答案呗。
代码:
///11111111111111111111111111111111111111111111
#include<bits/stdc++.h>
#define lson (i<<1)
#define rson (i<<1|1)using namespace std;
typedef long long ll;
const int N =200005;struct node
{int l,r;int mxid;ll lz;ll maxx;
}tr[N<<2];vector<int >ve[N];
int tim;
int L[N];
int R[N];
int dfns[N];
int dfn;
int f[N];
int vis[N];
ll w[N];
ll val[N];
int n;void dfs(int u,int fa)
{val[u]=val[fa]+w[u];f[u]=fa;dfns[++dfn]=u; L[u]=dfn;for(int i=0;i<ve[u].size();i++){int v=ve[u][i];if(v==fa) continue;dfs(v,u);}R[u]=dfn;
}void push_up(int i)
{ll &maxx=tr[i].maxx; int &mxid=tr[i].mxid;if(tr[lson].maxx>=tr[rson].maxx){maxx=tr[lson].maxx; mxid=tr[lson].mxid;}else{maxx=tr[rson].maxx; mxid=tr[rson].mxid;}
}void push_down(int i)
{ll &lz=tr[i].lz;if(lz){tr[lson].maxx-=lz; tr[lson].lz+=lz;tr[rson].maxx-=lz; tr[rson].lz+=lz;lz=0;}
}void build(int i,int l,int r)
{tr[i].l=l; tr[i].r=r; tr[i].lz=0; tr[i].maxx=0; tr[i].mxid=0;if(l==r){tr[i].maxx=val[dfns[l]];tr[i].mxid=dfns[l];return ;}int mid=(l+r)>>1;build(lson,l,mid);build(rson,mid+1,r);push_up(i);
}void update(int i,int l,int r,ll lz)
{if(tr[i].l==l&&tr[i].r==r){tr[i].maxx-=lz;tr[i].lz+=lz;return ;}push_down(i);int mid=(tr[i].l+tr[i].r)>>1;if(r<=mid) update(lson,l,r,lz);else if(l>mid) update(rson,l,r,lz);else{update(lson,l,mid,lz);update(rson,mid+1,r,lz);}push_up(i);
}int main()
{int k;scanf("%d %d",&n,&k);for(int i=1;i<=n;i++) scanf("%lld",&w[i]);int u,v;for(int i=1;i<n;i++){scanf("%d %d",&u,&v);ve[u].push_back(v);ve[v].push_back(u);}dfs(1,0);build(1,1,n);ll ans=0;while(k--){ans+=tr[1].maxx;int id=tr[1].mxid;while(1){if(id==0) break;if(vis[id]) break;int l,r;l=L[id]; r=R[id];update(1,l,r,w[id]);vis[id]=1;id=f[id];}}printf("%lld\n",ans);return 0;
}/// 222222222222222222222222222222222
#include<bits/stdc++.h>using namespace std;
typedef long long ll;
const int N =2e5+5;
vector<int >ve[N];struct merge_dui
{int l,r;int dis;ll val;
}T[N];
int root[N];
int cnode;ll w[N];
int n;int Merge(int r1,int r2)
{if(r1==0||r2==0) return r1+r2;if(T[r1].val<T[r2].val) swap(r1,r2);T[r1].r=Merge(T[r1].r,r2);if(T[T[r1].l].dis<T[T[r1].r].dis) swap(T[r1].l,T[r1].r);T[r1].dis=T[T[r1].r].dis+1;return r1;
}void dfs(int u,int fa)
{if(ve[u].size()==1&&fa!=-1){root[u]=++cnode;T[root[u]].val=w[u];return ;}root[u]=0;T[root[u]].val=0;for(int i=0;i<ve[u].size();i++){int v=ve[u][i];if(v==fa) continue;dfs(v,u);root[u]=Merge(root[u],root[v]);}T[root[u]].val+=w[u];return ;
}int Pop(int rt)
{return Merge(T[rt].l,T[rt].r);
}int main()
{int k,u,v;scanf("%d %d",&n,&k);for(int i=1;i<=n;i++) scanf("%lld",&w[i]);for(int i=1;i<n;i++){scanf("%d %d",&u,&v);ve[u].push_back(v);ve[v].push_back(u);}dfs(1,-1);ll ans=0;while(k--){ans+=T[root[1]].val;root[1]=Pop(root[1]);}printf("%lld\n",ans);return 0;
}
BZOJ 3252 攻略相关推荐
- BZOJ#3252. 攻略
BZOJ#3252. 攻略 题目描述 Solution 有一个显然的 贪心,每次选取一个到根的点权和最大的点xxx,将答案加上xxx到根的路径的点权和,并将xxx到根的路径上的点的权值清零. 可以使用 ...
- 【贪心】 BZOJ 3252:攻略
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 261 Solved: 90 [Submit][Status][Discuss] ...
- 【刷题】BZOJ 3252 攻略
Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏<XX 半岛>,这款游戏有n个场景(s ...
- [bzoj 3252]攻略
众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏<XX半岛>,这款游戏有n个场景(scene),某些场景可以通过不同的选择支到达其他场景.所 ...
- bzoj 3252: 攻略
题意 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏<XX半岛>,这款游戏有n个场景(scene),某些场景可以通过不同的选择支到达其他场 ...
- [HYSBZ - 3252] 攻略
问题描述 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏<XX 半岛>,这款游戏有n个场景(scene),某 ...
- bzoj3252攻略(线段树+dfs序)或者(树链剖分+dfs)
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1341 Solved: 642 [Submit][Status][Discuss] ...
- bzoj3252攻略 贪心+dfs序+线段树
题目链接:戳这里 3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 605 Solved: 255 [Submit][Status] ...
- bzoj3252攻略(线段树+dfs序)
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 562 Solved: 238 [Submit][Status][Discuss] ...
最新文章
- RHEL 5服务篇—修改MySQl数据库root密码的几种方式
- 数据分析入门:如何训练数据分析思维?
- 前端小知识点(4):JS 运行机制和存储
- 4万次下载,我的这本电子书连续数月蝉联阿里云下载榜冠军!!!
- 深入理解Java泛型
- Javascript实现返回上一页面并刷新
- Part Ⅱ At the Restaurant 在饭店??
- Ajax PHP 边学边练 之二 实例
- 若只有4KB内存可用,该如何打印数组中所有重复的元素
- 常用DNS列表(电信、网通)
- QQ微信域名防封 预防域名封禁 强制跳转至浏览器打开
- python3 import的一个细节
- window下nginx实现图片缩放实操
- 百度地图详解使用,显示自己的当前位置BaiduMap
- IMU:姿态解算算法集合
- 【操作系统】实验六 系统内存使用统计
- 发出警报声的c语言程序,PIC单片机警报声C程序
- 2022年山东省职业院校技能大赛中职组“网络搭建与应用”赛项规程
- 神经网络解决回归问题,神经网络做回归问题
- RICOH C4502彩色打印机取消双面打印功能