传送门

主席树经典题。

首先把树搞出来,然后搞出来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. react-native DatePicker日期选择组件的实现

    本教程的实现效果如下: 为了实现其淡入/淡出的覆盖效果, 还有取消按钮, 在此用了一个三方的组件, 大家可以先安装一下: 三方组件的地址:https://github.com/eyaleizenber ...

  2. Android 自带后退按钮的使用

    一.后退按钮有两种定义,分别是向上按钮和返回按钮:向上按钮:偏向于一种父子关系:返回按钮:反映的是一种前后关系 向上按钮:在清单文件中需要添加后退功能按钮的Activity中添加parentActiv ...

  3. GridView 树形结构分组的功能

    在“会飞的鱼”博客中看到GridView实现树形结构的代码,经过修改,添加了树形结构中的复选框功能,欢迎吐槽. 源地址:http://www.cnblogs.com/chhuic/archive/20 ...

  4. Keepalived+LVS+nginx双机热备

    Keepalived简介 什么是Keepalived呢,keepalived观其名可知,保持存活,在网络里面就是保持在线了, 也就是所谓的高可用或热备,用来防止单点故障的发生. Keepalived采 ...

  5. ORA-28000: the account is locked 账户被锁

    这种情况可能是因为你输入错误的用户名密码达到10次,oracle给你锁住了. 解决方法: 首先 ~bash$ sqlplus /nolog SQL> conn sys/sys as sysdba ...

  6. JS-- 浮点数运算处理

        一. 问题描述 最近在做一个项目,页面上会存在一些JS浮点数的运算,发现JS浮点数运算存在一些bug.譬如: 0.1+0.2 == 0.30000000000000004 0.1 + 0.7 ...

  7. Hanoi问题java解法

    用什么语言解法都差不多,思路都是一样,递归,这其中只要注重于开始和结果的状态就可以了,对于中间过程,并不需要深究.(我细细思考了一下,还是算了.=_=) 代码其实很简单注重的是思路. 问题描述:有一个 ...

  8. 新手!mass 设置问题

    mass就是你那个物体的质量啊质量越大,惯性也越大重力也越大.假如你的刚体的mass为1,那么你只要给这个物体9.81N向上的力,你就可以抵消重力,让这个物体悬浮着:但假如这个物体的mass为10,你 ...

  9. Introducing Holographic Emulation

    Holographic Emulation is a new feature that vastly reduces iteration time when developing holographi ...

  10. Mysql5.5升级到5.7后MySQLdb不能正常使用的问题解决

    ubuntu系统 报错信息1 Type "help", "copyright", "credits" or "license&qu ...