Description

在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿。在这个帮派里,有一名忍者被称之为 Master。除了 Master以外,每名忍者都有且仅有一个上级。为保密,同时增强忍者们的领导力,所有与他们工作相关的指令总是由上级发送给他的直接下属,而不允许通过其他的方式发送。现在你要招募一批忍者,并把它们派遣给顾客。你需要为每个被派遣的忍者 支付一定的薪水,同时使得支付的薪水总额不超过你的预算。另外,为了发送指令,你需要选择一名忍者作为管理者,要求这个管理者可以向所有被派遣的忍者 发送指令,在发送指令时,任何忍者(不管是否被派遣)都可以作为消息的传递 人。管理者自己可以被派遣,也可以不被派遣。当然,如果管理者没有被排遣,就不需要支付管理者的薪水。你的目标是在预算内使顾客的满意度最大。这里定义顾客的满意度为派遣的忍者总数乘以管理者的领导力水平,其中每个忍者的领导力水平也是一定的。写一个程序,给定每一个忍者 i的上级 Bi,薪水Ci,领导力L i,以及支付给忍者们的薪水总预算 M,输出在预算内满足上述要求时顾客满意度的最大值。
1  ≤N ≤ 100,000 忍者的个数;
1  ≤M ≤ 1,000,000,000 薪水总预算; 
 
0  ≤Bi < i  忍者的上级的编号;
1  ≤Ci ≤ M                     忍者的薪水;
1  ≤Li ≤ 1,000,000,000             忍者的领导力水平。

Input

从标准输入读入数据。
 
第一行包含两个整数 N M,其中 N表示忍者的个数,M表示薪水的总预算。
 
接下来 N行描述忍者们的上级、薪水以及领导力。其中的第 i 行包含三个整 Bi , C i , L i分别表示第i个忍者的上级,薪水以及领导力。Master满足B i = 0并且每一个忍者的老板的编号一定小于自己的编号 Bi < i

Output

输出一个数,表示在预算内顾客的满意度的最大值。
 
 

Sample Input

5 4
0 3 3
1 3 5
2 2 2
1 2 4
2 3 1

Sample Output

6

HINT

如果我们选择编号为 1的忍者作为管理者并且派遣第三个和第四个忍者,薪水总和为 4,没有超过总预算                         4。因为派遣了                              2   个忍者并且管理者的领导力为      3,

用户的满意度为 2      ,是可以得到的用户满意度的最大值。

Source

【分析】

什么启发式合并。叫得这么高端...不就是一个个插进去吗....

记得要用longlong

发现了一个很严重的问题,昨天的splay里面有问题。。

还是指针的问题....如果没有用引用的话就要返回,否则的话值不会变,貌似这个问题只有在以大小作为排序标准的情况下才会出现?

因为好像splay处理序列的时候一般是不需要根据大小排序的,所以一直没有发现....还好发现了,不然省选出现这个问题就跪了啊!!

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#define LOCAL
const int MAXN = + ;
const int INF = ;
const int SIZE = ;
const int maxnode = 0x7fffffff + ;
using namespace std;
vector<long long>G[MAXN];
stack<long long>S;
long long n;
long long b[MAXN];
long long c[MAXN], l[MAXN], m; struct SPLAY{
struct Node{
long long size;
long long val, sum;
Node *parent, *ch[]; long long cmp(){
if (parent->ch[] == this) return ;
else return ;
}
}*nil, _nil, mem[MAXN], *root[MAXN];
long long tot, pos;//pos表示当前根是哪一个 void update(Node *&t){
if (t == nil) return;
t->size = ;
t->size += t->ch[]->size + t->ch[]->size;
t->sum = t->val;
t->sum += t->ch[]->sum + t->ch[]->sum;
return;
}
void init(){
//循环哨兵
nil = &_nil;
_nil.val = _nil.size =_nil.sum = ;
_nil.parent = _nil.ch[] = _nil.ch[] = nil; tot = ;
//没有根就只能加一点特判断了
}
Node *NEW(long long val){
Node *p = &mem[tot++];
p->size = ;
p->val = p->sum = val;
p->parent = p->ch[] = p->ch[] = nil;
return p;
}
//旋转,d代表1右旋
void Rotate(Node *t, long long d){
Node *p = t->parent;
t = p->ch[d ^ ];
p->ch[d ^ ] = t->ch[d];
if (t->ch[d] != nil) t->ch[d]->parent = p;
t->ch[d] = p;
t->parent = p->parent;
//注意不是引用
if (t->parent != nil){
if (t->parent->ch[] == p) t->parent->ch[] = t;
else t->parent->ch[] = t;
}
p->parent = t;
if (t->parent == nil) root[pos] = t;
update(p);
update(t);
}
//没标记就是好TAT
Node* splay(Node *x, Node *y){
while (x->parent != y){
if (x->parent->parent == y){
Rotate(x, x->cmp() ^ );
break;
}else{
Rotate(x->parent, x->parent->cmp() ^ );
Rotate(x, x->cmp() ^ );
}
update(x);
}
update(x);
return x;
}
void insert(Node *&t, long long val){
if (t == nil){
t = NEW(val);
return;
}
Node *x = t;
Node *y = t;
while (){
long long d = (val >= x->val);
if (x->ch[d] == nil){
x->ch[d] = NEW(val);
x->ch[d]->parent = x;
//update(x);
t = splay(x->ch[d], nil);
return;
}else {x = x->ch[d];}
}
return;//不用update
}
void push(Node *&t){
if ( t == nil) return;
push(t->ch[]);
S.push(t->val);
push(t->ch[]);
}
//感动天地没有find!
Node* merge(Node *a, Node *b, long long pa, long long pb){
if (a == nil) return b;
else if (b == nil) return a;
//注意是将b插入a,为了启发式合并要判断大小
if (a->size < b->size){
//swap(root[pa], root[pb]);
swap(a, b);
}
push(b);//把p推到栈里面
while (!S.empty()){
insert(a, S.top());
S.pop();
}
//delete b;//可以删掉吧....
return a;
} //表示在Node*t中sum比m小
long long get(Node *t, long long val){
Node *x = t;
long long cnt = ;
while (){
if (x == nil) break;
if (val >= x->sum) {cnt += x->size; break;}//一次性全部拿完,包括子树
//能往左走当然尽量往左
long long tmp = (x->ch[]->sum);
//拿完左子树去右边拿
if (val >= (tmp + x->val)) {cnt += x->ch[]->size + ; val -= tmp + x->val; x = x->ch[];}
else x = x->ch[];//往左边拿
}
return cnt;
}
void work(){
init();
while (!S.empty()) S.pop();
long long Ans = ;
for (long long i = n; i >= ; i--){
if (G[i].size() == ){//叶子节点
root[i] = NEW(c[i]);
if (c[i] <= m) Ans = max(Ans, l[i]);
continue;
}
if (i == ){
//prlong long(root[8]);
//printf("\n\n\n");
}
root[i] = nil;//枚举每个管理者
pos = i;
insert(root[i], c[i]);
for (long long j = ; j < G[i].size(); j++){
long long v = G[i][j];
root[i] = merge(root[i], root[G[i][j]], i, v);
if (i == ){
// prlong long(root[3]);
//printf("\n\n\n");
}
}
//printf("%d\n", tot);
//if ((get(root[i], m) * l[i]) == 12)
//printf("");
if (i == ){
//printf("%d", root[3]->size);
//prlong long(root[8]);
}
Ans = max(Ans, get(root[i], m) * l[i]);
}
/*pos = n;
insert(root[n], 10);
insert(root[n], 1);*/
printf("%lld\n", Ans);
//printf("%d", tot);
}
/*void print(Node *t){
if (t == nil) return ;
prlong long(t->ch[0]);
printf("%lld %lld\n", t->val, t->parent->val);
prlong long(t->ch[1]);
}*/
void debug(){
init();
Node *p = NEW();
insert(p, );
printf("%lld", p->val);
}
}A; void read(){
//memest
long long sum = ;
scanf("%lld%lld", &n, &m);//m为薪水总预算
for (long long i = ; i <= n; i++){
//分别代表上级薪水领导力
scanf("%lld%lld%lld", &b[i], &c[i], &l[i]);
G[b[i]].push_back(i);
//sum += c[i];
//printf("%d %lld %d\n", b[i], c[i], (2568 / 428));
}
//第3个有6个
//printf("%d\n", m);
} int main(){ read();
A.work();
//A.debug();
return ;
}

【BZOJ2809】【splay启发式合并】dispatching的更多相关文章

  1. 【BZOJ-2809】dispatching派遣 Splay + 启发式合并

    2809: [Apio2012]dispatching Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2334  Solved: 1192[Submi ...

  2. 【BZOJ-2733】永无乡 Splay+启发式合并

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2048  Solved: 1078[Submit][Statu ...

  3. BZOJ2733 永无乡【splay启发式合并】

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  4. BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]

    2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...

  5. bzoj2733: [HNOI2012]永无乡(splay+启发式合并/线段树合并)

    这题之前写过线段树合并,今天复习Splay的时候想起这题,打算写一次Splay+启发式合并. 好爽!!! 写了长长的代码(其实也不长),只凭着下午的一点记忆(没背板子...),调了好久好久,过了样例, ...

  6. 【BZOJ2733】永无乡[HNOI2012](splay启发式合并or线段树合并)

    题目大意:给你一些点,修改是在在两个点之间连一条无向边,查询时求某个点能走到的点中重要度第k大的点.题目中给定的是每个节点的排名,所以实际上是求第k小:题目求的是编号,不是重要度的排名.我一开始差点被 ...

  7. 算法复习——splay+启发式合并(bzoj2733-永无乡)

    题目: Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通 ...

  8. 【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并

    启发式合并而已啦,, 调试时发现的错误点:insert后没有splay,把要拆开的树的点插入另一个树时没有把ch[2]和fa设为null,找第k大时没有先减k,,, 都是常犯的错误,比赛时再这么粗心就 ...

  9. 【洛谷P3224】永无乡 并查集+Splay启发式合并

    题目大意:给定 N 个点的图,点有点权,初始有一些无向边,现在有 Q 个询问,每个询问支持动态增加一条无向边连接两个不连通的点和查询第 X 个点所在的联通块中权值第 K 大的是哪个点. 题解:学会了平 ...

随机推荐

  1. 【转】在Ubuntu下编译Android源码并运行Emulator

    原文网址:http://www.mcuos.com/thread-4553-1-1.html 建立编译环境 1.在VirtualBox上安装Ubuntu 2.安装JDK   $ sudo apt-ge ...

  2. Delphi WebService 需要注意 转

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://gang4415.blog.51cto.com/225775/251997 Web ...

  3. suse linux 编译安装Apache时报“APR NOT FOUND”的解决方法

    今日编译apache时出错: #./configure --prefix……检查编辑环境时出现: checking for APR... noconfigure: error: APR not fou ...

  4. POJ 1503 Integer Inquiry 简单大数相加

    Description One of the first users of BIT's new supercomputer was Chip Diller. He extended his explo ...

  5. vimium快捷键列表

    最近越来越懒了,不想拿手去碰鼠标,就想这样放在键盘上,在MacOSX下基本的操作也都能实现了,Xcode也没什么问题,现在就是有个地方十分不方便,就是浏览网页的问题,不管怎么样都是需要鼠标来浏览网页, ...

  6. 武汉Uber优步司机奖励政策(1月25日~1月31日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  7. 与IO相关的等待事件troubleshooting-系列5

    'db file scattered read'         这是另一种常见的等待事件.他产生于Oracle从磁盘读取多个块到Buffer Cache中非连续(" scattered&q ...

  8. DB2 insert into 三种写法

    db2的insert into 支持三种格式,即:一次插入一行,一次插入多行和从SELECT语句中插入. 以表为例: create table “user" ( "name&quo ...

  9. UVa1608 UVaLive6258 Non-boring sequences

    填坑系列(p.248) 比较神 从两端枚举 最坏复杂度就成O(nlogn)了 #include<cstdio> #include<cstdlib> #include<al ...

  10. Nginx系列~负载均衡服务器与WWW服务器的实现

    上两讲主要是关于Nginx的环境的介绍,没有涉及到真正环境的开发,这次我们以一个实现的例子,来说明一下负载均衡服务器与WWW服务器的Nginx是如何配置的,并最终如何实现的. 如下是一个实际场景,一台 ...