传送门

主席树经典题。

首先把树搞出来,然后搞出来DFS序。然后离散化点权,在DFS序上建立主席树。

对于每个点对应的区间,查找对应的区间最大的点数即可。

//BZOJ2809
//by Cydiater
//2016.12.6
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
#include <bitset>
#include <set>
using namespace std;
#define ll long long
#define up(i,j,n)		for(int i=j;i<=n;i++)
#define down(i,j,n)		for(int i=j;i>=n;i--)
#define cmax(a,b)		a=max(a,b)
#define cmin(a,b)		a=min(a,b)
#define Auto(i,node)		for(int i=LINK[node];i;i=e[i].next)
#define FILE "dispatching"
const int MAXN=1e5+5;
const ll oo=1LL<<55;
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int N,root[MAXN],cnt=0,siz[MAXN],dfn[MAXN],dfs_clock=0;
ll M,va[MAXN],vb[MAXN],fsort[MAXN],rnum,val[MAXN],ans=0;
struct Graph{
	int LINK[MAXN],len;
	struct edge{
		int y,next;
	}e[MAXN<<1];
	inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;}
	inline void Insert(int x,int y){insert(x,y);insert(y,x);}
	void make_graph(){
		up(i,1,N){
			int fa=read();va[i]=read();vb[i]=read();
			fsort[i]=va[i];
			if(!fa)continue;
			Insert(i,fa);
		}
	}
	void dfs(int node,int father){
		siz[node]=1;dfn[++dfs_clock]=node;
		Auto(i,node)if(e[i].y!=father){
			dfs(e[i].y,node);
			siz[node]+=siz[e[i].y];
		}
	}
}G;
struct Chair_man_Tree{
	ll cost,sum;
	int son[2];
}t[MAXN<<5];
namespace solution{
	void init(){
		N=read();M=read();
		G.make_graph();
		G.dfs(1,0);
	}
	int NewNode(ll cost,int sum,int son0,int son1){
		t[++cnt].cost=cost;t[cnt].sum=sum;
		t[cnt].son[0]=son0;t[cnt].son[1]=son1;
		return cnt;
	}
	void insert(int leftt,int rightt,int &Root,int last,int pos){
		Root=NewNode(t[last].cost+fsort[pos],t[last].sum+1,t[last].son[0],t[last].son[1]);
		int mid=(leftt+rightt)>>1;
		if(leftt==rightt)	return;
		if(pos<=mid)		insert(leftt,mid,t[Root].son[0],t[last].son[0],pos);
		else			insert(mid+1,rightt,t[Root].son[1],t[last].son[1],pos);
	}
	ll Get(int S,int T,int leftt,int rightt,ll LIM){
		if(leftt==rightt)		return min(LIM/fsort[leftt],t[T].sum-t[S].sum);
		int mid=(leftt+rightt)>>1;
		ll cost=t[t[T].son[0]].cost-t[t[S].son[0]].cost;
		if(cost<=LIM)	return t[t[T].son[0]].sum-t[t[S].son[0]].sum+Get(t[S].son[1],t[T].son[1],mid+1,rightt,LIM-cost);
		else		return Get(t[S].son[0],t[T].son[0],leftt,mid,LIM);
	}
	void slove(){
		sort(fsort+1,fsort+N+1);
		rnum=unique(fsort+1,fsort+N+1)-(fsort+1);
		up(i,1,N)val[i]=lower_bound(fsort+1,fsort+rnum+1,va[dfn[i]])-fsort;
		up(i,1,N)insert(1,rnum,root[i],root[i-1],val[i]);
		up(i,1,N){
			int L=i,R=i+siz[dfn[i]]-1;
			cmax(ans,vb[dfn[i]]*Get(root[L-1],root[R],1,rnum,M));
		}
	}
	void output(){
		cout<<ans<<endl;
	}
}
int main(){
	//freopen("input.in","r",stdin);
	//freopen(FILE".in","r",stdin);
	//freopen(FILE".out","w",stdout);
	using namespace solution;
	init();
	slove();
	output();
	return 0;
}

BZOJ2809: [Apio2012]dispatching的更多相关文章

  1. bzoj2809 [Apio2012]dispatching(左偏树)

    [Apio2012]dispatching Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 M ...

  2. BZOJ2809 [Apio2012]dispatching 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2809 题意概括 n个点组成一棵树,每个点都有一个领导力和费用,可以让一个点当领导,然后在这个点的子 ...

  3. BZOJ2809——[Apio2012]dispatching

    1.题目大意:给一棵树和M值,每个点有两个权值C和L,选x个点,这x个点的C值的和不能超过M,且这x个点如果都在某个子树内 定义满意度为x*这个子树的根的L值 2.分析:这是一道可并堆的题目,我们考虑 ...

  4. [BZOJ2809][Apio2012]dispatching(左偏树)

    首先对于一个节点以及它的子树,它的最优方案显然是子树下选最小的几个 用左偏树维护出每棵子树最优方案的节点,记录答案 然后它的这棵树可以向上转移给父节点,将所有子节点的左偏树合并再维护就是父节点的最优方 ...

  5. 【DFS序】【莫队算法】【权值分块】bzoj2809 [Apio2012]dispatching

    题意:在树中找到一个点i,并且找到这个点子树中的一些点组成一个集合,使得集合中的所有点的c之和不超过M,且Li*集合中元素个数和最大 首先,我们将树处理出dfs序,将子树询问转化成区间询问. 然后我们 ...

  6. bzoj2809 [Apio2012]dispatching——左偏树(可并堆)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2809 思路有点暴力和贪心,就是 dfs 枚举每个点作为管理者: 当然它的子树中派遣出去的忍者 ...

  7. [BZOJ2809][Apio2012]dispatching 贪心+可并堆

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2809 我们考虑以每一个节点作为管理者所得的最优答案,一定是优先选择所要薪水少的忍者.那么首 ...

  8. 【BZOJ2809】[Apio2012]dispatching 可并堆

    [BZOJ2809][Apio2012]dispatching Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 M ...

  9. 【bzoj2809】[Apio2012]dispatching 左偏树

    2016-05-31  15:56:57 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2809 直观的思想是当领导力确定时,尽量选择薪水少的- ...

随机推荐

  1. js sort() reverse()

    数组中存在的两个方法:sort()和reverse() 直接用sort(),如下: ,,,,,,,,,,,]; console.log(array.sort());ps:[0, 1, 2, 2, 29 ...

  2. A星寻路算法介绍

    你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法 ...

  3. Linux用户态和内核态

    究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上,先看一个例子: 1)例 ...

  4. 我的敏捷、需求分析、UML、软件设计电子书 - 下载(持续更新中)

    我将所有我的电子书汇总在一起,方便大家下载!(持续更新) 文档保存在我的网站——软件知识原创基地上(www.umlonline.org),请放心下载. 1)软件设计是怎样炼成的?(2014-4-1 发 ...

  5. ASP.NET MVC 身份认证

    身份认证的好处就是, 如果这个页面没有登录, 刷新后会自动跳到登录页要求登录,保证了应用程序的安全.而Forms 身份认证是web下最常用的,如何配置呢?见下(基于mvc 4) 1.在webconfi ...

  6. Node.js 教程 02 - 经典的Hello World

    前言: Node.js的介绍.安装及配置,上一节都已经介绍过了,如果有不清楚的也可以留言或者直接问度娘. 本节: 本节主要以一个简单的例子简单体验一下Node.js,用到了两种方法.下面会介绍. 总之 ...

  7. Group by

    分组语句必须和聚合函数在一起使用, group by子句负责将数据分成逻辑组,聚合函数对每一组进行统计计算 group by 必须放到 select 语句后面,如果select语句中有where子句, ...

  8. YII2 载入默认值 loadDefaultValues

    本人很懒,所以喜欢找现成的东西来用,所以在载入默认值的时候我直接就选择了Yii2 自带的loadDefaultValues 问题来了,我提交的时候发现我在rules里面设置的default没有工作 [ ...

  9. MySQL 主从复制

    1 复制概述 Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重 ...

  10. linux 做gw(nat)详细配置

                          linux 做企业网关gw(nat)详细配置   最近因为公司的路由器老化导致上网时断时续,上半小时网就断一次网,为此我头疼不已,本着为公司节约成本的宗旨, ...